당신은 상범 빌딩에 갇히고 말았다. 여기서 탈출하는 가장 빠른 길은 무엇일까? 상범 빌딩은 각 변의 길이가 1인 정육면체(단위 정육면체)로 이루어져있다. 각 정육면체는 금으로 이루어져 있어 지나갈 수 없거나, 비어있어서 지나갈 수 있게 되어있다. 당신은 각 칸에서 인접한 6개의 칸(동,서,남,북,상,하)으로 1분의 시간을 들여 이동할 수 있다. 즉, 대각선으로 이동하는 것은 불가능하다. 그리고 상범 빌딩의 바깥면도 모두 금으로 막혀있어 출구를 통해서만 탈출할 수 있다.
당신은 상범 빌딩을 탈출할 수 있을까? 만약 그렇다면 얼마나 걸릴까?
입력은 여러 개의 테스트 케이스로 이루어지며, 각 테스트 케이스는 세 개의 정수 L, R, C로 시작한다. L(1 ≤ L ≤ 30)은 상범 빌딩의 층 수이다. R(1 ≤ R ≤ 30)과 C(1 ≤ C ≤ 30)는 상범 빌딩의 한 층의 행과 열의 개수를 나타낸다.
그 다음 각 줄이 C개의 문자로 이루어진 R개의 행이 L번 주어진다. 각 문자는 상범 빌딩의 한 칸을 나타낸다. 금으로 막혀있어 지나갈 수 없는 칸은 '#'으로 표현되고, 비어있는 칸은 '.'으로 표현된다. 당신의 시작 지점은 'S'로 표현되고, 탈출할 수 있는 출구는 'E'로 표현된다. 각 층 사이에는 빈 줄이 있으며, 입력의 끝은 L, R, C가 모두 0으로 표현된다. 시작 지점과 출구는 항상 하나만 있다.
각 빌딩에 대해 한 줄씩 답을 출력한다. 만약 당신이 탈출할 수 있다면 다음과 같이 출력한다.
Escaped in x minute(s)
여기서 x는 상범 빌딩을 탈출하는 데에 필요한 최단 시간이다.
만일 탈출이 불가능하다면, 다음과 같이 출력한다.
Trapped
3 4 5
S....
.###.
.##..
###.#
#####
#####
##.##
##...
#####
#####
#.###
####E
1 3 3
S##
#E#
###
0 0 0
Escaped in 11 minute(s).
Trapped!
- BFS 알고리즘 작성 시 3차원 공간과 이에 따른 6가지 이동가능 방향을 고려한다.
import sys
from collections import deque
# BFS Algorithm
def BFS(graph3D, start, end, height_len, row_len, col_len):
# 6가지 방향
dh = [1,-1,0,0,0,0]
dr = [0,0,1,-1,0,0]
dc = [0,0,0,0,1,-1]
# 큐 생성
queue = deque()
# 시작위치 반영
queue.append(start)
# 큐가 빌 때까지 반복합니다.
while queue:
cur_h, cur_r, cur_c = queue.popleft()
for i in range(6):
move_h = cur_h + dh[i]
move_r = cur_r + dr[i]
move_c = cur_c + dc[i]
# 주어진 영역을 벗어나지 않으면서 지나갈 수 있는 칸일 때
if 0 <= move_h <= height_len-1 and 0 <= move_r <= row_len-1 and 0 <= move_c <= col_len-1:
if graph3D[move_h][move_r][move_c] == 0:
graph3D[move_h][move_r][move_c] = graph3D[cur_h][cur_r][cur_c] + 1
queue.append([move_h, move_r, move_c])
# 이동 종료 후
# 탈출할 수 없을 때(출구 도달 불가)
h, r, c = end_loc
if graph3D[h][r][c] == 0:
print('Trapped!')
# 탈출할 수 있을 때
else:
print('Escaped in {} minute(s).'.format(graph3D[h][r][c]-1))
# 테스트 케이스가 주어집니다.
while True:
# L: 상범 빌딩의 층 수, R: 행 수, C: 열 수
L, R, C = map(int, sys.stdin.readline().split())
# L, R, C가 모두 0이면 테스트 종료
if L == 0 & R == 0 & C == 0:
break
# 빌딩 초기화
building = []
# 층의 정보가 주어집니다.
for _ in range(L):
# 층 초기화
floor = []
for _ in range(R):
floor.append(list(sys.stdin.readline().rstrip()))
# 빌딩에 층을 추가합니다.
building.append(floor)
# 공백 입력
space = sys.stdin.readline().rstrip()
# 비어있는 칸을 0으로 변경합니다. 시작지점, 종료지점을 따로 저장합니다.
for k in range(L):
for i in range(R):
for j in range(C):
if building[k][i][j] == '.':
building[k][i][j] = 0
elif building[k][i][j] == 'S':
start_loc = [k,i,j]
building[k][i][j] = 1
elif building[k][i][j] == 'E':
end_loc = [k,i,j]
building[k][i][j] = 0
# BFS Algorithm
BFS(building, start_loc, end_loc, L, R, C)