[BOJ] 백준 3055번 탈출 (Python)

deannn.Park·2021년 6월 22일
0

BOJ - 백준

목록 보기
7/42
post-thumbnail

문제

사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제일 친한 친구인 비버의 굴로 가능한 빨리 도망가 홍수를 피하려고 한다.

티떱숲의 지도는 R행 C열로 이루어져 있다. 비어있는 곳은 '.'로 표시되어 있고, 물이 차있는 지역은 '*', 돌은 'X'로 표시되어 있다. 비버의 굴은 'D'로, 고슴도치의 위치는 'S'로 나타내어져 있다.

매 분마다 고슴도치는 현재 있는 칸과 인접한 네 칸 중 하나로 이동할 수 있다. (위, 아래, 오른쪽, 왼쪽) 물도 매 분마다 비어있는 칸으로 확장한다. 물이 있는 칸과 인접해있는 비어있는 칸(적어도 한 변을 공유)은 물이 차게 된다. 물과 고슴도치는 돌을 통과할 수 없다. 또, 고슴도치는 물로 차있는 구역으로 이동할 수 없고, 물도 비버의 소굴로 이동할 수 없다.

티떱숲의 지도가 주어졌을 때, 고슴도치가 안전하게 비버의 굴로 이동하기 위해 필요한 최소 시간을 구하는 프로그램을 작성하시오.

고슴도치는 물이 찰 예정인 칸으로 이동할 수 없다. 즉, 다음 시간에 물이 찰 예정인 칸으로 고슴도치는 이동할 수 없다. 이동할 수 있으면 고슴도치가 물에 빠지기 때문이다.

입력

  • 첫째 줄에 50보다 작거나 같은 자연수 R과 C가 주어진다.
  • 다음 R개 줄에는 티떱숲의 지도가 주어지며, 문제에서 설명한 문자만 주어진다.
  • 'D'와 'S'는 하나씩만 주어진다.

출력

  • 첫째 줄에 고슴도치가 비버의 굴로 이동할 수 있는 가장 빠른 시간을 출력한다.
  • 만약, 안전하게 비버의 굴로 이동할 수 없다면, "KAKTUS"를 출력한다.

예제

입력 1

3 3
D.*
...
.S.

출력 1

3

 

입력 2

3 3
D.*
...
..S

출력 2

KAKTUS

 

입력 3

3 6
D...*.
.X.X..
....S.

출력 3

6

 

입력 4

5 4
.D.*
....
..X.
S.*.
....

출력 4

4

풀이

import sys
from collections import deque

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]

R, C = map(int, input().split())
matrix = list()

water = deque()
D = deque()
S = deque()

turn = 0

for i in range(R):
    tmp = input()
    matrix.append(tmp)
    if '*' in tmp:
        water.append([i, tmp.index('*')])
    if 'D' in tmp:
        D.append([i, tmp.index('D')])
    if 'S' in tmp:
        S.append([i, tmp.index('S')])


while S:
    turn += 1

# 고슴도치 이동
    next_S = []
    while S:
        s_now = S.popleft()
        if matrix[s_now[0]][s_now[1]] != 'S':
            continue
        for i in range(4):					# 상하좌우
            s_next = [s_now[0] + dx[i], s_now[1] + dy[i]]
            
            # 움직일 위치가 주어진 지도를 벗어나지 않고 그 곳이 물 또는 바위가 아니라면
            if 0 <= s_next[0] < R and 0 <= s_next[1] < C and matrix[s_next[0]][s_next[1]] not in ['*', 'X']:
                if matrix[s_next[0]][s_next[1]] == 'D':		# 비버의 굴 도착
                    print(turn)
                    sys.exit()					# 프로그램 종료
                    
                # 아직 도착 안한 경우. 다음 위치에 S 표시
                matrix[s_next[0]] = matrix[s_next[0]][:s_next[1]] + 'S' + matrix[s_next[0]][s_next[1] + 1:]
                next_S.append(s_next)				# 다음 위치를 queue에 넣음
        else:
            # 고슴도치가 이동했기 때문에 원 위치는 S -> . 변경
            matrix[s_now[0]] = matrix[s_now[0]][:s_now[1]] + '.' + matrix[s_now[0]][s_now[1] + 1:]
    S = deque(next_S)						# 다음 턴 때의 위치들

# 물 이동
    next_water = []
    while water:
        w_now = water.popleft()
        for i in range(4):
            w_next = [w_now[0] + dx[i], w_now[1] + dy[i]]
            
            # 움직일 위치가 주어진 지도를 벗어나지 않고 그 곳이 비었거나 고슴도치가 있다면
            if 0 <= w_next[0] < R and 0 <= w_next[1] < C and matrix[w_next[0]][w_next[1]] in ['.', 'S']:
                matrix[w_next[0]] = matrix[w_next[0]][:w_next[1]] + '*' + matrix[w_next[0]][w_next[1] + 1:]
                next_water.append(w_next)
    water = deque(next_water)


# 위의 while문에서 종료되지 않으면 비버의 굴에 도착 못한 것이므로
print("KAKTUS")

각 턴마다 고슴도치 먼저 이동 후 물 이동.
각자 위치는 queue로 넣어놓고, 고슴도치 이동 전에 현재 위치가 물로 차게 됬다면 실패한 것.

profile
컴퓨터 관련 여러 분야 공부중

0개의 댓글