結果
問題 | No.867 避難経路 |
ユーザー |
![]() |
提出日時 | 2025-03-31 17:40:06 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 7,337 bytes |
コンパイル時間 | 760 ms |
コンパイル使用メモリ | 82,816 KB |
実行使用メモリ | 318,704 KB |
最終ジャッジ日時 | 2025-03-31 17:42:47 |
合計ジャッジ時間 | 16,969 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 3 |
other | AC * 30 TLE * 6 -- * 5 |
ソースコード
import sysfrom collections import dequedef main():input = sys.stdin.read().split()ptr = 0H = int(input[ptr]); ptr +=1W = int(input[ptr]); ptr +=1gx = int(input[ptr])-1; ptr +=1gy = int(input[ptr])-1; ptr +=1A = []for _ in range(H):row = list(map(int, input[ptr:ptr+W]))ptr += WA.append(row)Q = int(input[ptr]); ptr +=1queries = []for _ in range(Q):x = int(input[ptr])-1; ptr +=1y = int(input[ptr])-1; ptr +=1k = int(input[ptr]); ptr +=1queries.append((x, y, k))# Precompute for each cell (i, j) the list of (L, S) pairs# 4 directionsdirs = [ (-1,0), (1,0), (0,-1), (0,1) ]# For each cell, store a list of (L, S) pairs# Initialize all cells with empty listscells = [ [ [] for _ in range(W) ] for _ in range(H) ]# priority_queue will be a deque, and for BFS, perhaps use a queue of cells to process# Starting with the exit cell# exit cell's (gx, gy)# L=1, S=A[gx][gy]exit_i = gxexit_j = gycells[exit_i][exit_j].append( (1, A[exit_i][exit_j]) )# BFS queue: each entry is (i, j)from collections import dequeq = deque()q.append( (exit_i, exit_j) )# Visited is not needed because cells can be processed multiple times, as long as new (L, S) pairs are added# For processing in BFS-like orderwhile q:i, j = q.popleft()# Explore neighborsfor di, dj in dirs:ni = i + dinj = j + djif 0 <= ni < H and 0 <= nj < W:# For each neighbor (ni, nj), we can generate new (L_new, S_new) = (L+1, S+A[ni][nj])# Check all existing pairs in (i,j)# For each existing (L, S), generate new (L+1, S + A[ni][nj])new_pairs = []for L, S in cells[i][j]:L_new = L + 1S_new = S + A[ni][nj]new_pairs.append( (L_new, S_new) )# Now, merge these new_pairs into the neighbor's cells[ni][nj]# For each new (L_new, S_new):# Check if it's dominated by any existing pair in cells[ni][nj]# And if it can dominate some existing pairs.added = Falsefor L_new, S_new in new_pairs:# Check against existing pairs# First, check if this new pair is not dominated by any existing pairdominated = Falseto_remove = []for idx, (L_ex, S_ex) in enumerate(cells[ni][nj]):if L_ex <= L_new and S_ex <= S_new:dominated = Truebreakif L_ex >= L_new and S_ex >= S_new:to_remove.append(idx)# Remove dominated pairs in reverse orderfor idx in reversed(to_remove):del cells[ni][nj][idx]if not dominated:# Now check if the new pair is not already in the list (but possibly with the same L and S)# Also, remove any existing pairs with L >= L_new and S >= S_new (dominated by new pair)# Now add the new paircells[ni][nj].append( (L_new, S_new) )added = True# After possible addition, sort the list by L, then S# Sort and remove duplicates if anyif added:# Sort the cells[ni][nj] list by L, then by Scells[ni][nj].sort()# Remove duplicates: if same L, keep the one with smaller Sunique = []for p in cells[ni][nj]:if not unique or p[0] != unique[-1][0]:unique.append(p)elif p[0] == unique[-1][0] and p[1] < unique[-1][1]:unique.pop()unique.append(p)cells[ni][nj] = unique# Also, add the neighbor to the queue to process its neighborsq.append( (ni, nj) )# Precompute convex hull for each cellhulls = [ [ [] for _ in range(W) ] for _ in range(H) ]for i in range(H):for j in range(W):# Build the convex hull for cells[i][j]points = cells[i][j]if not points:continue # Should not happen as per problem constraints, but safety# Sort points by L, then Spoints.sort()# Build lower convex hullhull = []for p in points:L, S = pwhile len(hull) >= 2:# Check if the last two points and current point form a convex turnL1, S1 = hull[-2]L2, S2 = hull[-1]# Cross product: (L2 - L1) * (S - S2) - (L - L2) * (S2 - S1)# For lower hull, we want this to be >= 0cross = (L2 - L1) * (S - S2) - (L - L2) * (S2 - S1)if cross <= 0:# Remove hull[-1]hull.pop()else:breakhull.append( (L, S) )hulls[i][j] = hull# Answer queriesfor x, y, k in queries:if x == exit_i and y == exit_j:# Already at exitprint(A[x][y] + k*k)continuehull = hulls[x][y]if not hull:# Not reachable (should not happen per problem statement)print(0)continuec = k * k# Find the optimal (L, S) in hull which minimizes c*L + S# Since hull is sorted by L, and the lower envelope is convex,# the optimal point can be found via binary searchleft = 0right = len(hull) - 1best = Nonebest_val = float('inf')# Check edge casesif len(hull) == 1:L, S = hull[0]print(c * L + S)continue# Binary searchwhile left <= right:mid = (left + right) // 2# Compute current valueL_mid, S_mid = hull[mid]val_mid = L_mid * c + S_mid# Compare with nextif mid < len(hull) -1:L_next, S_next = hull[mid+1]val_next = L_next * c + S_nextif val_next < val_mid:left = mid +1else:right = mid -1else:right = mid -1# Update bestif val_mid < best_val:best_val = val_midbest = mid# Final check around the left regionfor i in range(max(0, left-2), min(len(hull), left+3)):if i <0 or i >= len(hull):continueL, S = hull[i]val = L * c + Sif val < best_val:best_val = valprint(best_val)if __name__ == '__main__':main()