[Algorithm] BaekJoon : 2206. Pythonによる壁の破壊と移動
[問題のショートカット]https://www.acmicpc.net/problem/2206
N×Mのマトリックス表現のマッピングがあります.地図では、0は移動可能な位置、1は移動不可能な壁の位置を示す.(1,1)から(N,M)の位置に移動し、最短経路に移動します.最短パスとは、地図上の最小セルを通るパスで、開始セルと終了セルが含まれます.
移動中に壁を割ったり移動したりする経路がもっと短い場合は、壁を割って移動することができます.
1つのセルで移動できるセルは上下左右に隣接するセルです.
地図を指定すると、最短パスを解くプログラムが作成されます.
入力
第1行はN(1≦N≦1000),M(1≦M≦1000)を与える.次のN行はMの数字で地図を与えます.(1,1)と(N,M)は常に0であると仮定する.
しゅつりょく
1行目に最短距離を出力します.不可能な場合は-1を出力します.
人の解答を見てもわかりにくい問題.
最短距離を見つけるためにBFSを使うことは理解したが、問題の核心である「壁を壊すことができる」という正確な表現はなかった.
問題を解決するには、アクセスするかどうかを示す配列を既存の配列とは異なり、3 Dで表す必要があります.
対応する座標の移動距離(Move Distance)が入力されている場合は、3 D配列で壁を破るときの最短距離(Short Distance on on Wall)と壁を破らないときの最短距離(Short Distance on Wall None Wall)をそれぞれ検索します.アクセス[r][c][0]:破壁時(r,c)の最短距離 アクセス[r][c][1]:最短距離 (r,c)壁を破る必要はありません
また、参照するセルの行と列の座標もキューに含まれている場合は、壁が破られたかどうかを判断する値(0または1)を挿入する必要があります.
コードは次のとおりです.
📌問題の説明
N×Mのマトリックス表現のマッピングがあります.地図では、0は移動可能な位置、1は移動不可能な壁の位置を示す.(1,1)から(N,M)の位置に移動し、最短経路に移動します.最短パスとは、地図上の最小セルを通るパスで、開始セルと終了セルが含まれます.
移動中に壁を割ったり移動したりする経路がもっと短い場合は、壁を割って移動することができます.
1つのセルで移動できるセルは上下左右に隣接するセルです.
地図を指定すると、最短パスを解くプログラムが作成されます.
入力
第1行はN(1≦N≦1000),M(1≦M≦1000)を与える.次のN行はMの数字で地図を与えます.(1,1)と(N,M)は常に0であると仮定する.
しゅつりょく
1行目に最短距離を出力します.不可能な場合は-1を出力します.
💡 問題を解く
人の解答を見てもわかりにくい問題.
最短距離を見つけるためにBFSを使うことは理解したが、問題の核心である「壁を壊すことができる」という正確な表現はなかった.
問題を解決するには、アクセスするかどうかを示す配列を既存の配列とは異なり、3 Dで表す必要があります.
対応する座標の移動距離(Move Distance)が入力されている場合は、3 D配列で壁を破るときの最短距離(Short Distance on on Wall)と壁を破らないときの最短距離(Short Distance on Wall None Wall)をそれぞれ検索します.
また、参照するセルの行と列の座標もキューに含まれている場合は、壁が破られたかどうかを判断する値(0または1)を挿入する必要があります.
コードは次のとおりです.
import sys
from collections import deque
d = [(-1, 0), (1, 0), (0, 1), (0, -1)]
def bfs():
visited = [[[0] * 2 for _ in range(M)] for _ in range(N)]
queue = deque([(0, 0, 1)])
visited[0][0][1] = 1
while queue:
r, c, used = queue.popleft()
if r == N-1 and c == M-1:
return visited[r][c][used]
for idx in range(4):
nr = r + d[idx][0]
nc = c + d[idx][1]
if 0 <= nr < N and 0 <= nc < M:
if matrix[nr][nc] == 1 and used == 1: # 벽이고 아직 뚫지 않았다면
visited[nr][nc][0] = visited[r][c][1] + 1 # visited[nr][nc][0] 값 최신화
queue.append((nr, nc, 0))
elif matrix[nr][nc] == 0 and visited[nr][nc][used] == 0: # 이동 가능한 칸이며 아직 지나가지 않았다면
visited[nr][nc][used] = visited[r][c][used] + 1 # used 값에 따라 visited[nr][nc][used] 값 최신화
queue.append((nr, nc, used))
return -1
N, M = map(int, input().split())
matrix = [list(map(int, ''.join(sys.stdin.readline().rstrip()))) for _ in range(N)]
print(bfs())
Reference
この問題について([Algorithm] BaekJoon : 2206. Pythonによる壁の破壊と移動), 我々は、より多くの情報をここで見つけました https://velog.io/@djagmlrhks3/Algorithm-BaekJoon-2206.-벽-부수고-이동하기-by-Pythonテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol