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