結果
問題 |
No.96 圏外です。
|
ユーザー |
![]() |
提出日時 | 2025-04-16 01:14:03 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 782 ms / 5,000 ms |
コード長 | 3,894 bytes |
コンパイル時間 | 203 ms |
コンパイル使用メモリ | 81,636 KB |
実行使用メモリ | 146,820 KB |
最終ジャッジ日時 | 2025-04-16 01:15:25 |
合計ジャッジ時間 | 9,657 ms |
ジャッジサーバーID (参考情報) |
judge5 / 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 cross(o, a, b): return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) def convex_hull(points): if not points: return [] 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 rotating_calipers(hull): n = len(hull) if n <= 1: return 0.0 if n == 2: return math.hypot(hull[0][0] - hull[1][0], hull[0][1] - hull[1][1]) max_dist = 0.0 j = 1 for i in range(n): next_i = (i + 1) % n while True: next_j = (j + 1) % n a = (hull[next_i][0] - hull[i][0], hull[next_i][1] - hull[i][1]) b = (hull[next_j][0] - hull[j][0], hull[next_j][1] - hull[j][1]) cross_prod = a[0] * b[1] - a[1] * b[0] if cross_prod > 1e-8: j = next_j else: break current_dist = math.hypot(hull[i][0] - hull[j][0], hull[i][1] - hull[j][1]) if current_dist > max_dist: max_dist = current_dist return max_dist def main(): import sys input = sys.stdin.read().split() ptr = 0 n = int(input[ptr]) ptr += 1 if n == 0: print("1.000000000") return points = [] for _ in range(n): x = int(input[ptr]) y = int(input[ptr+1]) ptr +=2 points.append((x, y)) grid = defaultdict(list) for idx, (x, y) in enumerate(points): gx = x // 10 gy = y // 10 grid[(gx, gy)].append((x, y, idx)) uf = UnionFind(n) for idx in range(n): x, y = points[idx] gx = x // 10 gy = y // 10 for dx in (-1, 0, 1): for dy in (-1, 0, 1): key = (gx + dx, gy + dy) if key not in grid: continue for (nx, ny, j) in grid[key]: if j <= idx: continue dx_val = x - nx dy_val = y - ny dist_sq = dx_val * dx_val + dy_val * dy_val if dist_sq <= 100: uf.union(idx, 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(): m = len(group) if m == 0: continue if m == 1: d = 0.0 elif m == 2: d = math.hypot(group[0][0] - group[1][0], group[0][1] - group[1][1]) else: hull = convex_hull(group) if not hull: d = 0.0 else: d = rotating_calipers(hull) current_max = d + 2.0 if current_max > max_candidate: max_candidate = current_max answer = max(max_candidate, 1.0) print("{0:.9f}".format(answer)) if __name__ == "__main__": main()