2023-10-22-동국대SW역량강화캠프-4699. 불
문제
윌리는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 윌리는 출구를 향해 뛰고 있다.
매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 윌리는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 윌리는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 윌리가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다.
빌딩의 지도가 주어졌을 때, 얼마나 빨리 빌딩을 탈출할 수 있는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다.
각 테스트 케이스의 첫째 줄에는 빌딩 지도의 너비와 높이 w와 h가 주어진다. (1 ≤ w,h ≤ 1000)
다음 h개 줄에는 w개의 문자, 빌딩의 지도가 주어진다.
’.’: 빈 공간
‘#’: 벽
‘@’: 윌리의 시작 위치
‘*’: 불
각 지도에 @의 개수는 하나이다.
출력
각 테스트 케이스마다 빌딩을 탈출하는데 가장 빠른 시간을 출력한다. 빌딩을 탈출할 수 없는 경우에는 “IMPOSSIBLE”을 출력한다.
예제 1 입력
5
4 3
####
#*@.
####
7 6
###.###
#*#.#*#
#.....#
#.....#
#..@..#
#######
7 4
###.###
#....*#
#@....#
.######
5 5
.....
.***.
.*@*.
.***.
.....
3 3
###
#@#
###
예제 1 출력
2
5
IMPOSSIBLE
IMPOSSIBLE
IMPOSSIBLE
Source
from collections import deque
n = int(input())
for i in range(n):
w, h = map(int ,input().split())
_map = [list(input()) for _ in range(h)]
dist = [[0 for _ in range(w)] for _ in range(h)]
ans = w * h + 1
q = deque()
for _h in range(h):
for _w in range(w):
if(_map[_h][_w] == '@'):
x = _h
y = _w
_map[_h][_w] = '.' # 빈 공간으로 초기화
if(_map[_h][_w] == '*'):
q.append([_h, _w, 1])
_map[_h][_w] = '.' # 빈 공간으로 초기화
q.append([x, y, -1]) # d(거리)가 양수이면 방문한 곳, 음수이면 방문하지 않은 곳
while(True):
if(len(q) == 0):
break
x, y, d = q.popleft()
nd = 0
if(d > 0):
nd = d + 1
else:
nd = d - 1
if(x < 0 or x >= h or y < 0 or y >= w or _map[x][y] != '.' or dist[x][y] != 0):
continue
if(d < 0 and (x == 0 or x == h - 1 or y == 0 or y == w - 1)):
ans = min(ans, -d)
dist[x][y] = d
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
q.append([nx, ny, nd])
if(ans == (w * h + 1)):
print("IMPOSSIBLE")
else:
print(ans)