정육면체 모양의 빌딩에서 출발지에서부터 시작해 도착지에 도착할 수 있는지, 가능하다면 걸리는 최단 거리를 구하는 문제다.
인접한 칸인 동, 서, 남, 북, 상, 하로만 움직일 수 있으며 일부 칸은 막혀있어 이동할 수 없다.
처음에 입력값을 받을 때 문제가 발생했다.
입력을 처리하는 코드
building = [[list(read().rstrip()) for _ in range(R)] for _ in range(L)]
위 코드로 다음과 같은 예시를 입력했을 때
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
![]() | ![]() | ![]() |
---|---|---|
1층은 정상이지만 | 2층부터 빈 배열이 생기더니 | 3층에도 생겼다. |
왜 이런가 생각해봤더니 입력할 때 각 층을 구분하기 위해 한 줄을 비워놨기 때문이었다.
따라서 입력을 처리하는 코드를 다음과 같이 수정했다.
building = []
for _ in range(L):
building.append([list(read().rstrip()) for _ in range(R)])
read()
![]() | ![]() | ![]() |
---|---|---|
모든 층에 대한 | 입력이 | 잘 되었다. |
문제를 풀기 전에 입력이 잘 되는지 확인하는 습관이 있어서 다행이었다.
이제 문제를 풀어보자.
아이디어는 시작점부터 BFS로 각 경로를 방문 표시를 하며 탐색하고 목적지에 도달하면 탐색을 중단하는 것이다.
여기서 조심해야 할게 그래프 탐색 문제라고 DFS로 접근하면 안된다는 것이다.
문제를 읽어보면 탈출 유무를 확인하는 것 뿐만 아니라 탈출에 걸리는 최단 시간, 즉 최단 거리를 출력으로 요구한다.
DFS로도 풀 순 있지만 첫번째로 찾은 경로가 가장 짧다는 보장이 없기 때문에 모든 경로에 대해 탐색을 진행해야 한다.
따라서 해당 문제는 DFS가 아닌 BFS로 풀어야한다!
import sys
read = sys.stdin.readline
from collections import deque
dz = [-1, 1, 0, 0, 0, 0]
dy = [0, 0, -1, 1, 0, 0]
dx = [0, 0, 0, 0, -1, 1]
while(True):
L, R, C = map(int, read().split())
if L == 0 and R == 0 and C == 0:
break
building = []
for _ in range(L):
building.append([list(read().rstrip()) for _ in range(R)])
read()
visited = [[[False for _ in range(C)] for _ in range(R)] for _ in range(L)]
for z in range(L):
for y in range(R):
for x in range(C):
if building[z][y][x] == 'S':
start = (z, y, x, 0)
visited[z][y][x] = True
if building[z][y][x] == 'E':
end = (z, y, x)
queue = deque([start])
isEscaped = False
while queue:
z, y, x, count = queue.popleft()
if (z, y, x) == end:
isEscaped = True
print(f'Escaped in {count} minute(s).')
break
for i in range(6):
nz, ny, nx = z + dz[i], y + dy[i], x + dx[i]
if 0 <= nz < L and 0 <= ny < R and 0 <= nx < C and not visited[nz][ny][nx]:
if building[nz][ny][nx] != '#':
queue.append((nz, ny, nx, count + 1))
visited[nz][ny][nx] = True
if not isEscaped:
print('Trapped!')
building
에 저장하고, 같은 크기의 visited
에 방문 여부를 저장한다.