백준

[백준] 22944 죽음의 비 [Python, 파이썬]

YoonJuHan 2023. 10. 16. 17:34
  • 문제 : https://www.acmicpc.net/problem/22944
  • 🔑 BFS
    • 우산을 들고 있을 때, 안 들고 있을 때의 계산 처리
    • 우산을 들고 있으면 우산의 내구도만 내리고 다음 칸에 체력 저장
    • 우산을 안 들고 있으면 체력을 내리고 다음 칸에 체력 저장
    • 방문했던 곳은 현재 체력이 높을 때만 이동 (우산 때문에, 방문했던 곳의 체력보다 현재 체력이 더 많을 수 있어서)

 

import sys
from collections import deque
input = sys.stdin.readline

n, h, d = map(int, input().split())
MAP = [list(input()) for _ in range(n)]
start, end = [], []
visit = [[0] * n for _ in range(n)]

for i in range(n):
    if start and end:
        break
    for j in range(n):
        if MAP[i][j] == 'S':
            start = [i, j, h, 0, 0] 
            visit[i][j] = h
        elif MAP[i][j] == 'E':
            end = [i, j]

q = deque([start])

mx, my = [0, 0, 1, -1], [1, -1, 0, 0]

while q:
    x, y, hp, umbrella, dist = q.popleft()  # 시작 x, 시작 y, 체력, 우산 내구도, 거리

    for i in range(4):
        nx, ny = x + mx[i], y + my[i]

        if 0 <= nx < n and 0 <= ny < n:
            if MAP[nx][ny] == 'E':          # 안전 지대 도착
                print(dist+1)
                exit()
            
            next_hp = hp                    # 다음 칸에 넣을 체력
            next_umbrella = umbrella        # 다음 칸에 넣을 우산 내구도

            if MAP[nx][ny] == 'U':          # 다음 칸이 우산이면
                next_umbrella = d           # 우산 내구도를 넣어준다.
            
            if next_umbrella == 0:          # 우산을 들고있지 않으면
                next_hp -= 1                # 체력 깎는다.
            else:                           # 우산 들고있으면
                next_umbrella -= 1          # 우산 내구도 깎는다.

            if visit[nx][ny] < next_hp:     # 다음 칸에 저장된 체력보다 계산된 체력이 많으면 이동
                visit[nx][ny] = next_hp     
                q.append([nx, ny, next_hp, next_umbrella, dist + 1])

print(-1)