結果
| 問題 |
No.1497 Triangle
|
| コンテスト | |
| ユーザー |
👑 tatyam
|
| 提出日時 | 2021-05-02 02:25:39 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 550 ms / 2,000 ms |
| コード長 | 2,794 bytes |
| コンパイル時間 | 324 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 112,104 KB |
| 最終ジャッジ日時 | 2024-07-20 10:34:38 |
| 合計ジャッジ時間 | 14,768 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 47 |
ソースコード
from collections import defaultdict
from math import *
EPS = 1e-10
INF = float("inf")
N = int(input())
P = [tuple(map(int, input().split())) for i in range(N)]
P.sort(reverse=True)
def cross(i, j, k):
x0, y0 = P[i]
x1, y1 = P[j]
x2, y2 = P[k]
x1 -= x0
x2 -= x0
y1 -= y0
y2 -= y0
return x1 * y2 - x2 * y1
def dot(i, j, k):
x0, y0 = P[i]
x1, y1 = P[j]
x2, y2 = P[k]
x1 -= x0
x2 -= x0
y1 -= y0
y2 -= y0
return x1 * x2 + y1 * y2
def normal(i, j):
return atan2(P[j][1] - P[i][1], P[j][0] - P[i][0]) + pi / 2
class Line:
def __init__(self):
self.mn = INF
self.mx = -INF
self.rev = False
def update(self, sl):
if sl < 0:
sl += 2 * pi
if self.rev and sl < pi:
sl += 2 * pi
if self.mn > sl:
self.mn = sl
if self.mx < sl:
self.mx = sl
assert pi > self.mx - self.mn >= 0
lines = defaultdict(Line)
for i in range(N - 1):
if P[i][0] != P[i + 1][0]:
lines[(1 << i + 1) - 1].rev = True
for i in range(N):
for j in range(N):
if i == j:
continue
bit1 = 0
bit2 = 0
for k in range(N):
c = cross(i, j, k)
if c > 0:
bit1 ^= 1 << k
bit2 ^= 1 << k
elif c == 0:
if dot(i, j, k) > 0:
bit1 ^= 1 << k
else:
bit2 ^= 1 << k
theta = normal(i, j)
lines[bit1].update(theta - EPS)
lines[bit2].update(theta + EPS)
lines = list(lines.items())
ans = [False] * (1 << N)
ans[0] = ans[-1] = True
for bit1, _ in lines:
for bit2, _ in lines:
ans[bit1 & bit2] = True
def solve(l1, r1, l2, r2, l3, r3):
if l1 > l2:
l1, l2 = l2, l1
r1, r2 = r2, r1
if l2 > l3:
l2, l3 = l3, l2
r2, r3 = r3, r2
if l1 > l2:
l1, l2 = l2, l1
r1, r2 = r2, r1
if max(r1, r2, r3) - min(l1, l2, l3) < pi:
return False
l1 += 2 * pi
r1 += 2 * pi
if max(r1, r2, r3) - min(l1, l2, l3) < pi:
return False
l2 += 2 * pi
r2 += 2 * pi
if max(r1, r2, r3) - min(l1, l2, l3) < pi:
return False
return True
L = len(lines)
for i in range(L):
bit1, l1 = lines[i]
for j in range(i):
bit2, l2 = lines[j]
if not (bit1 & bit2 and bit1 & ~bit2 and ~bit1 & bit2):
continue
for k in range(j):
bit3, l3 = lines[k]
if not (bit1 & bit2 & bit3 and bit1 & bit2 & ~bit3 and bit1 & ~bit2 & bit3 and ~bit1 & bit2 & bit3):
continue
if solve(l1.mn, l1.mx, l2.mn, l2.mx, l3.mn, l3.mx):
ans[bit1 & bit2 & bit3] = True
print(sum(ans))
tatyam