結果
| 問題 |
No.1413 Dynamic Sushi
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 00:35:56 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,599 bytes |
| コンパイル時間 | 446 ms |
| コンパイル使用メモリ | 82,200 KB |
| 実行使用メモリ | 83,008 KB |
| 最終ジャッジ日時 | 2025-04-16 00:39:28 |
| 合計ジャッジ時間 | 6,857 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 4 TLE * 1 -- * 20 |
ソースコード
import math
import heapq
def main():
N, W = map(int, input().split())
sushi = []
for _ in range(N):
X, Y, R, V, A = map(int, input().split())
sushi.append((X, Y, R, V, A))
# Initialize the priority queue with the starting state (time 0, mask 0, last -1, position (0,0))
heap = []
heapq.heappush(heap, (0.0, 0, -1, 0.0, 0.0))
best = {}
best[(0, -1)] = (0.0, 0.0, 0.0)
answer = float('inf')
while heap:
current_time, mask, last, x_prev, y_prev = heapq.heappop(heap)
# If this state has been processed with a better time, skip
if (mask, last) in best and best[(mask, last)][0] < current_time:
continue
# Check if all sushi are collected
if mask == (1 << N) - 1:
answer = min(answer, current_time)
continue
# Process transitions to each next sushi
for i in range(N):
if not (mask & (1 << i)):
X_i, Y_i, R_i, V_i, A_i = sushi[i]
# Function to compute f(dt) = distance - W * dt
def compute_f(dt):
t = current_time + dt
theta = (V_i * t + A_i) * math.pi / 180.0
x = X_i + R_i * math.cos(theta)
y = Y_i + R_i * math.sin(theta)
dx = x - x_prev
dy = y - y_prev
distance = math.hypot(dx, dy)
return distance - W * dt
# Find the minimal dt >= 0 where compute_f(dt) == 0
dt = 0.0
f0 = compute_f(dt)
found = False
if abs(f0) < 1e-9:
found = True
elif f0 > 0:
# Need to find upper bound where compute_f becomes negative
dt_high = 1e-8
while compute_f(dt_high) > 0:
dt_high *= 2
if dt_high > 1e20:
break # Safeguard against infinite loop
# Now perform binary search between dt_low=0 and dt_high
dt_low = 0.0
for _ in range(100):
dt_mid = (dt_low + dt_high) / 2
f_mid = compute_f(dt_mid)
if f_mid > 0:
dt_low = dt_mid
else:
dt_high = dt_mid
dt = dt_high
# Verify if the found dt is valid
if compute_f(dt) <= 1e-6:
found = True
else:
# f0 < 0, which is impossible since distance can't be negative
continue
if not found:
continue # No valid dt found, skip this transition
t = current_time + dt
theta = (V_i * t + A_i) * math.pi / 180.0
x = X_i + R_i * math.cos(theta)
y = Y_i + R_i * math.sin(theta)
new_mask = mask | (1 << i)
new_key = (new_mask, i)
# Update best time if this is better
if t < best.get(new_key, (float('inf'), 0, 0))[0]:
best[new_key] = (t, x, y)
heapq.heappush(heap, (t, new_mask, i, x, y))
print("{0:.15f}".format(answer))
if __name__ == "__main__":
main()
lam6er