結果
問題 | No.2180 Comprehensive Line Segments |
ユーザー |
![]() |
提出日時 | 2022-11-28 17:36:35 |
言語 | PyPy3 (7.3.15) |
結果 |
MLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 3,459 bytes |
コンパイル時間 | 276 ms |
コンパイル使用メモリ | 82,716 KB |
実行使用メモリ | 1,622,432 KB |
最終ジャッジ日時 | 2024-11-17 01:41:05 |
合計ジャッジ時間 | 67,738 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 MLE * 2 |
other | AC * 11 WA * 1 TLE * 4 MLE * 9 |
ソースコード
import sysfrom collections import dequefrom fractions import Fraction as fracinput = sys.stdin.readlineclass Vector2:def __init__(self, x: frac, y: frac):self.x = xself.y = ydef __eq__(self, other):return (self.x == other.x and self.y == other.y)def __hash__(self):return hash((self.x, self.y))def __sub__(self, other):return Vector2(other.x - self.x, other.y - self.y)def normalize(self):assert(self.x != 0 or self.y != 0)norm = self.x ** 2 + self.y ** 2self.x *= abs(self.x) / normself.y *= abs(self.y) / normreturn selfclass Line:def __init__(self, a: frac, b:frac, c:frac):self.a = aself.b = bself.c = cdef __eq__(self, other):return (self.a == other.a and self.b == other.b and self.c == other.c)def __hash__(self):return hash((self.a, self.b, self.c))def calc_line(one: Vector2, other: Vector2) -> Line:if(one == other):return Nonex1 = one.x; y1 = one.yx2 = other.x; y2 = other.yif(x1 == x2):return Line(1, 0, x1)a = (y1 - y2) / (x1 - x2)c = y1 - a * x1return Line(-a, 1, c)def calc_intersection(one: Line, other: Line) -> Vector2:p = one.a * other.b - other.a * one.bif(p == 0):return Noneq = other.b * one.c - one.b * other.cx = q / py = (other.c - other.a * x) / other.b if(one.b == 0) else (one.c - one.a * x) / one.breturn Vector2(x, y)"""Main Code"""# 入力N = int(input())P = [Vector2(*map(frac, input().split())) for _ in [0] * N]# 点が 1 個のときは必ず答えは 1if(N == 1):print(1)exit(0)# 各点に番号付けpoint_dic = {}point_num = 0for p in P:point_dic[p] = point_numpoint_num += 1# 有り得る直線を調べて番号付けline_dic = {}line_num = 0for i in range(N - 1):for j in range(i + 1, N):p1, p2 = P[i], P[j]line = calc_line(p1, p2)if(line in line_dic):continueline_dic[line] = line_numline_num += 1# 有り得る交点を調べて番号付けline_lis = list(line_dic.keys())for i in range(line_num - 1):for j in range(i + 1, line_num):l1, l2 = line_lis[i], line_lis[j]p = calc_intersection(l1, l2)if((p is None) or p in point_dic):continueP.append(p)point_dic[p] = point_numpoint_num += 1# 任意の2点について、2点から構成されるベクトルを調べて正規化vec_lis = [[None]*point_num for _ in [0]*point_num]for i in range(point_num - 1):for j in range(i + 1, point_num):if(calc_line(P[i], P[j]) not in line_dic):continuevec_lis[i][j] = (P[j] - P[i]).normalize()vec_lis[j][i] = (P[i] - P[j]).normalize()# グラフ探索dp = [[[N]*point_num for _ in [0]*point_num] for _ in [0]*(1 << N)]que = deque([])for i in range(N):que.append((0, 1 << i, i, i))dp[1 << i][i][i] = 0goal = (1 << N) - 1ans = Nwhile(que):c_now, b_now, v_prev, v_now = que.popleft()if(c_now > dp[b_now][v_prev][v_now]):continueif(b_now == goal):ans = c_nowbreakfor v_next in range(point_num):if(v_now == v_next or min(v_now, v_next) >= N or (vec_lis[v_now][v_next] is None)):continueb_next = b_now | (1 << v_next) if(v_next < N) else b_nowc_next = c_nowif(v_prev == v_now or vec_lis[v_prev][v_now] != vec_lis[v_now][v_next]):c_next += 1if(c_next >= dp[b_next][v_now][v_next]):continuedp[b_next][v_now][v_next] = c_nextif(c_next == c_now):que.appendleft((c_next, b_next, v_now, v_next))else:que.append((c_next, b_next, v_now, v_next))print(ans)