結果
| 問題 |
No.611 Day of the Mountain
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 20:29:28 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 4,198 bytes |
| コンパイル時間 | 188 ms |
| コンパイル使用メモリ | 82,760 KB |
| 実行使用メモリ | 93,960 KB |
| 最終ジャッジ日時 | 2025-06-12 20:29:45 |
| 合計ジャッジ時間 | 6,763 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / 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()
gew1fw