結果
問題 |
No.96 圏外です。
|
ユーザー |
![]() |
提出日時 | 2025-04-16 01:14:08 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 727 ms / 5,000 ms |
コード長 | 3,752 bytes |
コンパイル時間 | 325 ms |
コンパイル使用メモリ | 82,120 KB |
実行使用メモリ | 136,044 KB |
最終ジャッジ日時 | 2025-04-16 01:15:43 |
合計ジャッジ時間 | 9,787 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 28 |
ソースコード
import sys 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 distance_sq(p1, p2): dx = p1[0] - p2[0] dy = p1[1] - p2[1] return dx * dx + dy * dy def convex_hull(points): points = sorted(points) if len(points) <= 1: return points lower = [] for p in points: while len(lower) >= 2 and ( (lower[-1][0] - lower[-2][0]) * (p[1] - lower[-2][1]) - (lower[-1][1] - lower[-2][1]) * (p[0] - lower[-2][0]) ) <= 0: lower.pop() lower.append(p) upper = [] for p in reversed(points): while len(upper) >= 2 and ( (upper[-1][0] - upper[-2][0]) * (p[1] - upper[-2][1]) - (upper[-1][1] - upper[-2][1]) * (p[0] - upper[-2][0]) ) <= 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_sq = 0.0 j = 1 for i in range(n): next_i = (i + 1) % n dx1 = hull[next_i][0] - hull[i][0] dy1 = hull[next_i][1] - hull[i][1] while True: next_j = (j + 1) % n dx2 = hull[next_j][0] - hull[j][0] dy2 = hull[next_j][1] - hull[j][1] cross = dx1 * dy2 - dy1 * dx2 if cross > 0: j = next_j dx1 = hull[next_i][0] - hull[i][0] dy1 = hull[next_i][1] - hull[i][1] else: break current_dist_sq = (hull[i][0] - hull[j][0])**2 + (hull[i][1] - hull[j][1])**2 if current_dist_sq > max_dist_sq: max_dist_sq = current_dist_sq return math.sqrt(max_dist_sq) def main(): input = sys.stdin.read().split() ptr = 0 N = int(input[ptr]) ptr += 1 if N == 0: print("1.000000000") return points = [] grid = defaultdict(list) for i in range(N): x = int(input[ptr]) y = int(input[ptr + 1]) ptr += 2 points.append((x, y)) cell_x = x // 10 cell_y = y // 10 grid[(cell_x, cell_y)].append(i) uf = UnionFind(N) for i in range(N): x, y = points[i] cell_x = x // 10 cell_y = y // 10 for dx in (-1, 0, 1): for dy in (-1, 0, 1): key = (cell_x + dx, cell_y + dy) if key not in grid: continue for j in grid[key]: if j == i: continue if distance_sq(points[i], points[j]) <= 100: uf.union(i, j) groups = defaultdict(list) for i in range(N): root = uf.find(i) groups[root].append(points[i]) D_max = 0.0 for group in groups.values(): if len(group) == 0: continue hull = convex_hull(group) if not hull: continue d = rotating_calipers(hull) if d > D_max: D_max = d ans = max(1.0, D_max + 2.0) print("{0:.9f}".format(ans)) if __name__ == '__main__': main()