백준 알고리즘
[백준/Python]2206_벽 부수고 이동하기
헝그리개발자
2021. 6. 8. 13:16
문제
https://www.acmicpc.net/problem/2206
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
풀이
BFS와 3차원 배열을 사용했습니다.
최단 거리를 저장할 3차원 배열 visited를 선언하고 0으로 초기화 합니다.(visited[0][0][1] = 1)
smash가 1일 경우 벽을 뚫을 수 있는 상태라는 것을 나타냅니다.
- 큐에서 popleft한 값이 벽일 경우(1)
- smash가 1일 때
- 벽을 부수고 smash를 0으로 변경하여 큐에 푸쉬하고, visited[yy][xx][0] 갱신
- smash가 0일 때
- continue
- smash가 1일 때
- 큐에서 popleft한 값이 벽이 아닐 경우(0)
- 큐에 푸쉬하고 visited[yy][xx][smash] 갱신
코드
import sys
from collections import deque
def bfs():
q = deque([(0, 0, 1)])
visited = [[[0] * 2 for _ in range(m)] for _ in range(n)]
visited[0][0][1] = 1
while q:
y, x, smash = q.popleft() # smash가 1이면 벽을 뚫을 수 있다
if y == n - 1 and x == m - 1:
return visited[y][x][smash]
for i in range(4):
yy = y + dy[i]
xx = x + dx[i]
if 0 <= yy < n and 0 <= xx < m:
if matrix[yy][xx] == 1 and smash == 1:
visited[yy][xx][0] = visited[y][x][1] + 1
q.append((yy, xx, 0))
elif matrix[yy][xx] == 0 and visited[yy][xx][smash] == 0:
visited[yy][xx][smash] = visited[y][x][smash] + 1
q.append((yy, xx, smash))
return -1
n, m = map(int, sys.stdin.readline().rstrip().split())
matrix = []
for _ in range(n):
s = list(map(int, list(sys.stdin.readline().rstrip())))
matrix.append(s)
dy = [-1, 0, 1, 0]
dx = [0, -1, 0, 1]
print(bfs())