Category
프로그래밍  PS

[백준 / python] 5427: 불

2024년 09월 10일 by Hwang

https://www.acmicpc.net/problem/5427

문제

상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다.

매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다.

빌딩의 지도가 주어졌을 때, 얼마나 빨리 빌딩을 탈출할 수 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 테스트 케이스는 최대 100개이다.

각 테스트 케이스의 첫째 줄에는 빌딩 지도의 너비와 높이 w와 h가 주어진다. (1 ≤ w,h ≤ 1000)

다음 h개 줄에는 w개의 문자, 빌딩의 지도가 주어진다.

각 지도에 @의 개수는 하나이다.

출력

각 테스트 케이스마다 빌딩을 탈출하는데 가장 빠른 시간을 출력한다. 빌딩을 탈출할 수 없는 경우에는 "IMPOSSIBLE"을 출력한다.


풀이

import sys
from collections import deque

def escape():
    move = 0
    while players:
        move += 1
        total_count = len(players)
        for _ in range(total_count):
            i, j = players.popleft()
            if board[i][j] == "*":
                continue
            for dir_r, dir_c in dirs:
                new_r, new_c = i + dir_r, j + dir_c
                if not 0 <= new_r < h or not 0 <= new_c < w:
                    return move
                if board[new_r][new_c] == "#" or board[new_r][new_c] == "*":
                    continue
                if board[new_r][new_c] == "@":
                    continue
                board[new_r][new_c] = "@"
                players.append((new_r, new_c))
        spread_fire()
    return -1

def spread_fire():
    total_count = len(fires)
    for _ in range(total_count):
        i, j = fires.popleft()
        for dir_r, dir_c in dirs:
            new_r, new_c = i + dir_r, j + dir_c
            if not 0 <= new_r < h or not 0 <= new_c < w:
                continue
            if board[new_r][new_c] == "#" or board[new_r][new_c] == "*":
                continue
            board[new_r][new_c] = "*"
            fires.append((new_r, new_c))

dirs = ((0, 1), (0, -1), (1, 0), (-1, 0))
T = int(sys.stdin.readline())

for _ in range(T):
    w, h = map(int, sys.stdin.readline().split())
    board = [list(sys.stdin.readline().strip()) for _ in range(h)]
    players, fires = deque(), deque()
    for r in range(h):
        for c in range(w):
            if board[r][c] == '@':
                players.append((r, c))
            if board[r][c] == '*':
                fires.append((r, c))

    result = escape()
    if result == -1:
        print("IMPOSSIBLE")
    else:
        print(result)


 Comment