結果
問題 |
No.96 圏外です。
|
ユーザー |
![]() |
提出日時 | 2025-04-16 01:12:24 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 773 ms / 5,000 ms |
コード長 | 3,548 bytes |
コンパイル時間 | 499 ms |
コンパイル使用メモリ | 82,248 KB |
実行使用メモリ | 140,632 KB |
最終ジャッジ日時 | 2025-04-16 01:14:19 |
合計ジャッジ時間 | 10,341 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 28 |
ソースコード
import math from collections import defaultdict class UnionFind: def __init__(self, size): self.parent = list(range(size)) self.rank = [0] * size def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union(self, x, y): x_root = self.find(x) y_root = self.find(y) if x_root == y_root: return if self.rank[x_root] < self.rank[y_root]: self.parent[x_root] = y_root else: self.parent[y_root] = x_root if self.rank[x_root] == self.rank[y_root]: self.rank[x_root] += 1 def convex_hull(points): points = sorted(points) lower = [] for p in points: while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0: lower.pop() lower.append(p) upper = [] for p in reversed(points): while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0: upper.pop() upper.append(p) return lower[:-1] + upper[:-1] def cross(o, a, b): return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) def rotating_calipers(points): n = len(points) if n == 1: return 0.0 if n == 2: return math.hypot(points[0][0] - points[1][0], points[0][1] - points[1][1]) max_dist = 0.0 k = 1 for i in range(n): ni = (i + 1) % n while True: nk = (k + 1) % n val = cross(points[i], points[ni], points[nk]) - cross(points[i], points[ni], points[k]) if val > 1e-9: k = nk else: break current_dist = math.hypot(points[i][0] - points[k][0], points[i][1] - points[k][1]) if current_dist > max_dist: max_dist = current_dist return max_dist def main(): import sys input = sys.stdin.read().split() idx = 0 N = int(input[idx]) idx += 1 if N == 0: print(1.0) return points = [] for _ in range(N): x = float(input[idx]) y = float(input[idx + 1]) points.append((x, y)) idx += 2 uf = UnionFind(N) grid = defaultdict(list) for i in range(N): x, y = points[i] gx = int(math.floor(x / 10.0)) gy = int(math.floor(y / 10.0)) grid[(gx, gy)].append(i) dx = [-1, 0, 1] dy = [-1, 0, 1] for i in range(N): x1, y1 = points[i] gx = int(math.floor(x1 / 10.0)) gy = int(math.floor(y1 / 10.0)) for dgx in dx: for dgy in dy: ngx = gx + dgx ngy = gy + dgy if (ngx, ngy) in grid: for j in grid[(ngx, ngy)]: if j == i: continue x2, y2 = points[j] dist_sq = (x1 - x2)**2 + (y1 - y2)**2 if dist_sq <= 100.0 + 1e-9: uf.union(i, j) groups = defaultdict(list) for i in range(N): root = uf.find(i) groups[root].append(points[i]) max_candidate = 0.0 for group in groups.values(): if len(group) == 0: continue ch = convex_hull(group) d = rotating_calipers(ch) candidate = d + 2.0 if candidate > max_candidate: max_candidate = candidate result = max(max_candidate, 1.0) print("{0:.9f}".format(result)) if __name__ == "__main__": main()