백준 2206 - 벽 부수고 이동하기 (Python3)
코드
from collections import deque
n, m = map(int, input().split())
graph = []
for _ in range(n):
graph.append(list(map(int, input())))
# 3차원 행렬 => 마지막 요소 : 벽 파괴 가능 유무 확인
# visited[x][y][0] : 벽을 뚫지 않고 x, y까지 도착하는 경우
# visited[x][y][1] : 벽을 뚫고 x, y까지 도착하는 경우
visited = [[[0] * 2 for _ in range(m)] for _ in range(n)]
visited[0][0][0] = 1
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs(x, y, z):
q = deque()
q.append((x, y, z))
while q:
x, y, z = q.popleft()
# 끝 점에 도달하면 이동 횟수 출력
# 도달했으면 끝까지 갈 수 있다는 의미
if x == (n-1) and y == (m-1):
return visited[x][y][z]
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
# 맵을 벗어나면 반복 넘김
if nx < 0 or nx >= n or ny < 0 or ny >= m:
continue
# 다음 이동할 곳이 벽이고, 벽을 파괴하지 않은 경우
if graph[nx][ny] == 1 and z == 0:
visited[nx][ny][1] = visited[x][y][0] + 1
# z를 1로 넘김 => 벽을 파괴했으므로 1
q.append((nx, ny, 1))
# 다음 이동할 곳이 벽이 아니고, 방문한 적이 없으면
elif graph[nx][ny] == 0 and visited[nx][ny][z] == 0:
visited[nx][ny][z] = visited[x][y][z] + 1
q.append((nx, ny, z))
return -1
print(bfs(0, 0, 0))
문제 해설
BFS의 심화 문제.
‘벽을 한 번 뚫을 수 있다’ 라는 심플한 조건이 생겼을 뿐인데, 문제에 접근하는 것이 어려워 구글링을 하였다. DFS, BFS 문제를 어렵게 내면 정말 심화될 수 있다는 것을 깨닫게 해준 문제…
벽은 단 한 번만 뚫을 수 있으므로, 3차원 배열로 벽을 뚫었는지 뚫지 않았는지 두 경우에 대한 최단 거리를 각각 기록하여, 마지막까지 도착한 경우의 값을 정답으로 출력하면 된다. 이 때, x와 y가 마지막까지 도달하지 못하는 경우는 -1을 return 해줌으로써 문제를 해결할 수 있다.
댓글남기기