結果
問題 |
No.1413 Dynamic Sushi
|
ユーザー |
![]() |
提出日時 | 2025-03-20 20:26:54 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,147 bytes |
コンパイル時間 | 154 ms |
コンパイル使用メモリ | 82,708 KB |
実行使用メモリ | 142,584 KB |
最終ジャッジ日時 | 2025-03-20 20:28:31 |
合計ジャッジ時間 | 5,866 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 4 TLE * 1 -- * 20 |
ソースコード
import math def main(): import sys input = sys.stdin.read().split() idx = 0 N = int(input[idx]); idx +=1 W = float(input[idx]); idx +=1 X = [] Y = [] R = [] V = [] A = [] for _ in range(N): x = float(input[idx]); idx +=1 y = float(input[idx]); idx +=1 r = float(input[idx]); idx +=1 v = float(input[idx]); idx +=1 a = float(input[idx]); idx +=1 X.append(x) Y.append(y) R.append(r) V.append(v) A.append(a) INF = float('inf') dp = [[INF]*N for _ in range(1<<N)] # Initialize first step for v in range(N): # From (0,0) at time 0 to sushi v x_prev = 0.0 y_prev = 0.0 t_prev = 0.0 Xv = X[v] Yv = Y[v] Rv = R[v] Vv = V[v] Av = A[v] # Function to calculate the required earliest time def xvt(t): return Xv + Rv * math.cos( (Vv * t + Av) * math.pi / 180 ) def yvt(t): return Yv + Rv * math.sin( (Vv * t + Av) * math.pi / 180 ) left = t_prev right = t_prev if math.hypot(x_prev - xvt(left), y_prev - yvt(left)) <= W * (left - t_prev): dp[1<<v][v] = left continue # Find right such that distance <= W*(right - t_prev) found = False step = 1e-8 right = left + step for _ in range(100): xr = xvt(right) yr = yvt(right) d = math.hypot(x_prev - xr, y_prev - yr) if d <= W*(right - t_prev): found = True break step *= 2 right += step if not found: # This should not happen as per problem statement continue # Binary search between left and right for _ in range(100): mid = (left + right)/2 xmid = xvt(mid) ymid = yvt(mid) d_mid = math.hypot(x_prev -xmid, y_prev -ymid) if d_mid <= W*(mid - t_prev): right = mid else: left = mid dp[1<<v][v] = right # Iterate all masks for mask in range(1<<N): for u in range(N): if not (mask & (1<<u)): continue current_time = dp[mask][u] if current_time == INF: continue # Current position is sushi u's position at current_time xu = X[u] + R[u] * math.cos( (V[u] * current_time + A[u]) * math.pi / 180 ) yu = Y[u] + R[u] * math.sin( (V[u] * current_time + A[u]) * math.pi / 180 ) for v in range(N): if mask & (1<<v): continue # Calculate earliest t_next >= current_time for sushi v Xv_val = X[v] Yv_val = Y[v] Rv_val = R[v] Vv_val = V[v] Av_val = A[v] def xvt(t): return Xv_val + Rv_val * math.cos( (Vv_val * t + Av_val) * math.pi / 180 ) def yvt(t): return Yv_val + Rv_val * math.sin( (Vv_val * t + Av_val) * math.pi / 180 ) left = current_time right = current_time # Check if left is already feasible d_left = math.hypot(xu - xvt(left), yu - yvt(left)) if d_left <= W * (left - current_time): t_candidate = left else: # Find upper bound step = 1e-8 right = left + step found = False for _ in range(100): xr = xvt(right) yr = yvt(right) d = math.hypot(xu -xr, yu -yr) if d <= W*(right - current_time): found = True break step *= 2 right += step if not found: continue # should not happen # Binary search for _ in range(100): mid = (left + right)/2 xmid = xvt(mid) ymid = yvt(mid) d_mid = math.hypot(xu -xmid, yu -ymid) if d_mid <= W*(mid - current_time): right = mid else: left = mid t_candidate = right new_mask = mask | (1<<v) if t_candidate < dp[new_mask][v]: dp[new_mask][v] = t_candidate full_mask = (1<<N) -1 min_time = INF for u in range(N): if dp[full_mask][u] < min_time: min_time = dp[full_mask][u] print("{0:.15f}".format(min_time)) if __name__ == '__main__': main()