結果
| 問題 |
No.1413 Dynamic Sushi
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 00:47:24 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,028 ms / 4,000 ms |
| コード長 | 4,933 bytes |
| コンパイル時間 | 142 ms |
| コンパイル使用メモリ | 82,480 KB |
| 実行使用メモリ | 78,268 KB |
| 最終ジャッジ日時 | 2025-04-16 00:50:44 |
| 合計ジャッジ時間 | 19,544 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 25 |
ソースコード
import math
def main():
import sys
input = sys.stdin.read().split()
idx = 0
N = int(input[idx])
idx += 1
W = int(input[idx])
idx += 1
sushi = []
for _ in range(N):
X = int(input[idx])
Y = int(input[idx+1])
R = int(input[idx+2])
V = int(input[idx+3])
A = int(input[idx+4])
sushi.append((X, Y, R, V, A))
idx +=5
INF = float('inf')
dp = [[INF] * N for _ in range(1 << N)]
# Precompute initial times for each sushi
for i in range(N):
X, Y, R, V, A = sushi[i]
low = 0.0
high = 0.0
theta = (V * 0 + A) * math.pi / 180
x = X + R * math.cos(theta)
y = Y + R * math.sin(theta)
dist_sq = x**2 + y**2
if dist_sq <= 0.0:
T_i = 0.0
else:
high = 1.0
found = False
for _ in range(100):
theta_high = (V * high + A) * math.pi / 180
x_high = X + R * math.cos(theta_high)
y_high = Y + R * math.sin(theta_high)
dist_sq_high = x_high**2 + y_high**2
if dist_sq_high <= (W * high)**2:
found = True
break
high *= 2
if high > 1e20:
break
if not found:
continue
for _ in range(100):
mid = (low + high) / 2
theta_mid = (V * mid + A) * math.pi / 180
x_mid = X + R * math.cos(theta_mid)
y_mid = Y + R * math.sin(theta_mid)
dist_sq_mid = x_mid**2 + y_mid**2
if dist_sq_mid <= (W * mid)**2:
high = mid
else:
low = mid
T_i = high
if T_i < INF:
mask = 1 << i
dp[mask][i] = T_i
# Process all masks
for mask in range(1 << N):
for j in range(N):
if not (mask & (1 << j)) or dp[mask][j] == INF:
continue
current_time = dp[mask][j]
Xj, Yj, Rj, Vj, Aj = sushi[j]
theta_j = (Vj * current_time + Aj) * math.pi / 180
xj = Xj + Rj * math.cos(theta_j)
yj = Yj + Rj * math.sin(theta_j)
for i in range(N):
if mask & (1 << i):
continue
Xi, Yi, Ri, Vi, Ai = sushi[i]
low = current_time
high = current_time
theta_i = (Vi * current_time + Ai) * math.pi / 180
xi = Xi + Ri * math.cos(theta_i)
yi = Yi + Ri * math.sin(theta_i)
dx = xj - xi
dy = yj - yi
dist_sq = dx**2 + dy**2
time_diff = current_time - current_time
if dist_sq <= (W * time_diff)**2:
T_i = current_time
else:
high = current_time + 1.0
found = False
for _ in range(100):
t = high
theta_i_high = (Vi * t + Ai) * math.pi / 180
xi_high = Xi + Ri * math.cos(theta_i_high)
yi_high = Yi + Ri * math.sin(theta_i_high)
dx_high = xj - xi_high
dy_high = yj - yi_high
dist_sq_high = dx_high**2 + dy_high**2
time_diff_high = t - current_time
if dist_sq_high <= (W * time_diff_high)**2:
found = True
break
high *= 2
if high > current_time + 1e20:
break
if not found:
continue
for _ in range(100):
mid = (low + high) / 2
theta_i_mid = (Vi * mid + Ai) * math.pi / 180
xi_mid = Xi + Ri * math.cos(theta_i_mid)
yi_mid = Yi + Ri * math.sin(theta_i_mid)
dx_mid = xj - xi_mid
dy_mid = yj - yi_mid
dist_sq_mid = dx_mid**2 + dy_mid**2
time_diff_mid = mid - current_time
if dist_sq_mid <= (W * time_diff_mid)**2:
high = mid
else:
low = mid
T_i = high
if T_i < INF:
new_mask = mask | (1 << i)
if T_i < dp[new_mask][i]:
dp[new_mask][i] = T_i
full_mask = (1 << N) - 1
min_time = INF
for j in range(N):
if dp[full_mask][j] < min_time:
min_time = dp[full_mask][j]
print("{0:.11f}".format(min_time))
if __name__ == '__main__':
main()
lam6er