結果
問題 |
No.3154 convex polygon judge
|
ユーザー |
![]() |
提出日時 | 2025-05-21 04:28:47 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 925 ms / 2,000 ms |
コード長 | 2,628 bytes |
コンパイル時間 | 463 ms |
コンパイル使用メモリ | 82,772 KB |
実行使用メモリ | 113,268 KB |
最終ジャッジ日時 | 2025-05-21 04:28:56 |
合計ジャッジ時間 | 8,160 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 44 |
ソースコード
#yukicoder 3154 convex polygon judge #Convex Hull: 凸包を求める SortedP: (x, y)を辞書順昇順に並べた点群 def Convex_Hull(SortedP): outer_product = lambda x1, y1, x2, y2: x1 * y2 - x2 * y1 stack = [] for x, y in SortedP: #上側凸包 while len(stack) > 1: x1, y1 = stack[-2] x2, y2 = stack[-1] if outer_product(x2 - x1, y2 - y1, x - x2, y - y2) >= 0: stack.pop() # > を >= にすると経路上の点を削除できる else: break stack.append((x, y)) T = len(stack) for x, y in SortedP[-2::-1]: #下側凸包 while len(stack) > T: x1, y1 = stack[-2] x2, y2 = stack[-1] if outer_product(x2 - x1, y2 - y1, x - x2, y - y2) >= 0: stack.pop() else: break stack.append((x, y)) return stack[:-1] #入力受取 N = int(input()) P = [tuple(map(int, input().split())) for _ in range(N)] ''' #テスト1: 凸包貼るだけ print('Yes' if len( Convex_Hull(sorted(P)) ) == N else 'No') ''' #テスト2: ちゃんと考える #内積: 0ならPとQは垂直 外積: 正ならQは反時計回り側, 負なら時計側 outer_product = lambda P, Q: P[0] * Q[1] - P[1] * Q[0] #Pをソート P.sort() #上側凸包を計算 stack = [] for Xi, Yi in P: while len(stack) >= 2: X2, Y2 = stack[-2] #ふたつ前 X1, Y1 = stack[-1] #ひとつ前 #-2 → -1 と -2 → now(または-1 → now) を比較する #凸包を満たすなら、-2 → -1 のベクトルより時計回り側に位置する # → なので、反時計回りにある限りstackから除けばよい dX, dY = X1 - X2, Y1 - Y2 eX, eY = Xi - X2, Yi - Y2 if outer_product( (dX, dY), (eX, eY) ) >= 0: #正なら反時計回り stack.pop() else: break stack.append( (Xi, Yi) ) #下側凸包を計算 このままstackに積む upper_len = len( stack ) #現在の凸包 これは固定 for i in range( len(P) - 2, -1, -1 ): Xi, Yi = P[i] while len(stack) > upper_len: #ここを変更 上側凸包はかならず保護すること X2, Y2 = stack[-2] #ふたつ前 X1, Y1 = stack[-1] #ひとつ前 dX, dY = X1 - X2, Y1 - Y2 eX, eY = Xi - X2, Yi - Y2 if outer_product( (dX, dY), (eX, eY) ) >= 0: stack.pop() else: break stack.append( (Xi, Yi) ) #stack[0] == stack[-1]なので除去 assert len(stack) >= 2 and stack[0] == stack.pop() #答えを出力 print( 'Yes' if len(stack) == N else 'No' )