結果
| 問題 |
No.96 圏外です。
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 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()
lam6er