結果
| 問題 |
No.3154 convex polygon judge
|
| コンテスト | |
| ユーザー |
navel_tos
|
| 提出日時 | 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' )
navel_tos