結果
| 問題 | No.3504 Insert Maze |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-04-18 00:41:25 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 1,345 ms / 2,000 ms |
| コード長 | 3,976 bytes |
| 記録 | |
| コンパイル時間 | 340 ms |
| コンパイル使用メモリ | 85,248 KB |
| 実行使用メモリ | 257,372 KB |
| 最終ジャッジ日時 | 2026-04-18 00:42:42 |
| 合計ジャッジ時間 | 43,704 ms |
|
ジャッジサーバーID (参考情報) |
judge3_1 / judge1_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 85 |
ソースコード
import sys
def solve():
input_data = sys.stdin.read().split()
if not input_data:
return
H = int(input_data[0])
W = int(input_data[1])
grid_str = "".join(input_data[2:])
INF = 10**8
N = H * W
distS = [INF] * N
distG = [INF] * N
q = [0] * N
# BFS from S
head = 0
tail = 1
q[0] = 0
distS[0] = 0
Wm1 = W - 1
while head < tail:
u = q[head]
head += 1
d = distS[u] + 1
u_c = u % W # % 演算を1回に減らして高速化
if u >= W:
v = u - W
if distS[v] == INF and grid_str[v] != '#':
distS[v] = d
q[tail] = v
tail += 1
if u < N - W:
v = u + W
if distS[v] == INF and grid_str[v] != '#':
distS[v] = d
q[tail] = v
tail += 1
if u_c != 0:
v = u - 1
if distS[v] == INF and grid_str[v] != '#':
distS[v] = d
q[tail] = v
tail += 1
if u_c != Wm1:
v = u + 1
if distS[v] == INF and grid_str[v] != '#':
distS[v] = d
q[tail] = v
tail += 1
# BFS from G
head = 0
tail = 1
target = N - 1
q[0] = target
distG[target] = 0
while head < tail:
u = q[head]
head += 1
d = distG[u] + 1
u_c = u % W
if u >= W:
v = u - W
if distG[v] == INF and grid_str[v] != '#':
distG[v] = d
q[tail] = v
tail += 1
if u < N - W:
v = u + W
if distG[v] == INF and grid_str[v] != '#':
distG[v] = d
q[tail] = v
tail += 1
if u_c != 0:
v = u - 1
if distG[v] == INF and grid_str[v] != '#':
distG[v] = d
q[tail] = v
tail += 1
if u_c != Wm1:
v = u + 1
if distG[v] == INF and grid_str[v] != '#':
distG[v] = d
q[tail] = v
tail += 1
ans = distS[target]
if H + W < ans:
ans = H + W
def check_insertion(S_in, G_out, length):
res = INF
min_S = INF
for i in range(length):
s_val = S_in[i] - i
if s_val < min_S:
min_S = s_val
val = min_S + G_out[i] + i
if val < res:
res = val
min_S = INF
for i in range(length - 1, -1, -1):
s_val = S_in[i] + i
if s_val < min_S:
min_S = s_val
val = min_S + G_out[i] - i
if val < res:
res = val
return res + 2
# 行の挿入チェック
for r in range(H - 1):
idx1 = r * W
idx2 = idx1 + W
S0 = distS[idx1 : idx2]
S1 = distS[idx2 : idx2 + W]
G0 = distG[idx1 : idx2]
G1 = distG[idx2 : idx2 + W]
# S, G それぞれ
S_in = [s0 if s0 < s1 else s1 for s0, s1 in zip(S0, S1)]
G_out = [g0 if g0 < g1 else g1 for g0, g1 in zip(G0, G1)]
res = check_insertion(S_in, G_out, W)
if res < ans:
ans = res
# 列の挿入チェック
S_cols = [distS[c::W] for c in range(W)]
G_cols = [distG[c::W] for c in range(W)]
for c in range(W - 1):
S0 = S_cols[c]
S1 = S_cols[c + 1]
G0 = G_cols[c]
G1 = G_cols[c + 1]
S_in = [s0 if s0 < s1 else s1 for s0, s1 in zip(S0, S1)]
G_out = [g0 if g0 < g1 else g1 for g0, g1 in zip(G0, G1)]
res = check_insertion(S_in, G_out, H)
if res < ans:
ans = res
print(ans)
if __name__ == '__main__': ##あとけす
solve()