結果
問題 |
No.611 Day of the Mountain
|
ユーザー |
![]() |
提出日時 | 2025-06-12 15:20:00 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,198 bytes |
コンパイル時間 | 260 ms |
コンパイル使用メモリ | 82,772 KB |
実行使用メモリ | 93,692 KB |
最終ジャッジ日時 | 2025-06-12 15:20:24 |
合計ジャッジ時間 | 6,749 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | -- * 3 |
other | TLE * 1 -- * 8 |
ソースコード
import sys from collections import deque MOD = 201712111 def main(): H, W = map(int, sys.stdin.readline().split()) grid = [] original = [] # To keep the original grid for checking '?' for _ in range(H): line = sys.stdin.readline().strip() original.append(line) row = [] for c in line: if c == '?': row.append(1) else: row.append(int(c)) grid.append(row) # Compute minimal path sum T # Using BFS since all weights are positive INF = float('inf') dist = [[INF for _ in range(W)] for __ in range(H)] dist[0][0] = grid[0][0] q = deque() q.append((0,0)) dirs = [(0,1), (1,0)] while q: i,j = q.popleft() current = dist[i][j] for di, dj in dirs: ni, nj = i + di, j + dj if 0 <= ni < H and 0 <= nj < W: if dist[ni][nj] > current + grid[ni][nj]: dist[ni][nj] = current + grid[ni][nj] q.append((ni, nj)) T = dist[H-1][W-1] # Now find all minimal paths # Collect the minimal paths as sets of (i,j) positions # For each cell, compute the number of ways to reach it with minimal distance ways = [[0 for _ in range(W)] for __ in range(H)] ways[0][0] = 1 for i in range(H): for j in range(W): if i == 0 and j == 0: continue total = 0 if i > 0 and dist[i][j] == dist[i-1][j] + grid[i][j]: total += ways[i-1][j] if j > 0 and dist[i][j] == dist[i][j-1] + grid[i][j]: total += ways[i][j-1] ways[i][j] = total # Now, collect all minimal paths using backtracking paths = [] path = [] def backtrack(i, j): if i == 0 and j == 0: paths.append(path[::-1]) return if i > 0 and dist[i][j] == dist[i-1][j] + grid[i][j]: path.append((i-1, j)) backtrack(i-1, j) path.pop() if j > 0 and dist[i][j] == dist[i][j-1] + grid[i][j]: path.append((i, j-1)) backtrack(i, j-1) path.pop() backtrack(H-1, W-1) # Now, for each path, collect the set of '?' cells q_cells = set() for i in range(H): for j in range(W): if original[i][j] == '?': q_cells.add((i,j)) total_q = len(q_cells) # Extract for each path the set of '?' cells path_q_sets = [] for path in paths: s = set() for (i,j) in path: if original[i][j] == '?': s.add( (i,j) ) path_q_sets.append(s) # Now, we need to compute the inclusion-exclusion # For all non-empty subsets of paths, compute the union of their q cells # And accumulate the contributions # Since the number of paths can be large, we need to manage this efficiently # To optimize, we can precompute the list of unique q sets unique_q_sets = [] seen = set() for s in path_q_sets: frozen = frozenset(s) if frozen not in seen: seen.add(frozen) unique_q_sets.append(s) K = len(unique_q_sets) if K == 0: print(T) print(0) return # Now, iterate over all non-empty subsets of unique_q_sets # For each subset, compute the union of their q sets # Then compute 9^(total_q - size_of_union) # Multiply by (-1)^(|subset| + 1) and add to X X = 0 for mask in range(1, 1 << K): bits = bin(mask).count('1') # Get the subset subset = [] for i in range(K): if mask & (1 << i): subset.append(unique_q_sets[i]) # Compute the union union = set() for s in subset: union.update(s) k = len(union) m = total_q - k term = pow(9, m, MOD) if bits % 2 == 1: X = (X + term) % MOD else: X = (X - term) % MOD X = (X + MOD) % MOD # Ensure non-negative print(T) print(X % MOD) if __name__ == '__main__': main()