結果
| 問題 |
No.1413 Dynamic Sushi
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 00:51:24 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,046 ms / 4,000 ms |
| コード長 | 3,516 bytes |
| コンパイル時間 | 518 ms |
| コンパイル使用メモリ | 81,692 KB |
| 実行使用メモリ | 77,712 KB |
| 最終ジャッジ日時 | 2025-04-16 00:53:29 |
| 合計ジャッジ時間 | 19,927 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 25 |
ソースコード
import math
def main():
import sys
input = sys.stdin.read().split()
idx = 0
N, W = int(input[idx]), int(input[idx+1])
idx += 2
sushis = []
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])
sushis.append((X, Y, R, V, A))
idx += 5
INF = float('inf')
dp = [[INF] * (N + 1) for _ in range(1 << N)]
dp[0][N] = 0.0 # Starting at virtual node (0,0) at time 0
for mask in range(1 << N):
for last in range(N + 1):
if dp[mask][last] == INF:
continue
if mask == (1 << N) - 1:
continue
for i in range(N):
if (mask >> i) & 1:
continue
# Compute previous position and time
if last == N:
x_prev, y_prev = 0.0, 0.0
t_prev = dp[mask][last]
else:
X_prev, Y_prev, R_prev, V_prev, A_prev = sushis[last]
t_prev_current = dp[mask][last]
angle_prev = (V_prev * t_prev_current + A_prev) * math.pi / 180.0
x_prev = X_prev + R_prev * math.cos(angle_prev)
y_prev = Y_prev + R_prev * math.sin(angle_prev)
t_prev = t_prev_current
# Compute for sushi i
X_i, Y_i, R_i, V_i, A_i = sushis[i]
# Initial check at t_prev
angle_i_prev = (V_i * t_prev + A_i) * math.pi / 180.0
x_i_prev = X_i + R_i * math.cos(angle_i_prev)
y_i_prev = Y_i + R_i * math.sin(angle_i_prev)
dx = x_i_prev - x_prev
dy = y_i_prev - y_prev
d_initial_sq = dx * dx + dy * dy
if d_initial_sq < 1e-9:
t_new = t_prev
else:
S_i = R_i * abs(V_i) * math.pi / 180.0
d_initial = math.sqrt(d_initial_sq)
upper_bound = t_prev + d_initial / (W - S_i) + 1.0
low = t_prev
high = upper_bound
best_t = None
eps = 1e-8
for _ in range(100):
mid = (low + high) / 2
angle_i = (V_i * mid + A_i) * math.pi / 180.0
x_i = X_i + R_i * math.cos(angle_i)
y_i = Y_i + R_i * math.sin(angle_i)
dx_curr = x_i - x_prev
dy_curr = y_i - y_prev
distance_sq = dx_curr ** 2 + dy_curr ** 2
allowed = W * (mid - t_prev)
allowed_sq = allowed ** 2
if distance_sq <= allowed_sq + 1e-9:
best_t = mid
high = mid - eps
else:
low = mid + eps
if best_t is None:
continue
t_new = best_t
new_mask = mask | (1 << i)
if t_new < dp[new_mask][i]:
dp[new_mask][i] = t_new
full_mask = (1 << N) - 1
min_time = INF
for i in range(N):
if dp[full_mask][i] < min_time:
min_time = dp[full_mask][i]
print("{0:.11f}".format(min_time))
if __name__ == '__main__':
main()
lam6er