코테 노트/백준

백준 3055 탈출 Python 3

화요밍 2022. 2. 8. 15:03
728x90
반응형

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

 

3055번: 탈출

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

www.acmicpc.net

 

최종 코드

 

GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음

백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.

github.com

import sys
from collections import deque

def fill_up_water():
    edge = len(water)
    while edge:
        x, y = water.popleft()
        for ddx, ddy in zip(dx, dy):
            nx, ny = x+ddx, y+ddy
            if 0 <= nx < C and 0 <= ny < R and forest[ny][nx] == '.':
                forest[ny][nx] = '*'
                water.append([nx, ny])
        edge -= 1

def escape():
    while q:
        fill_up_water()

        edge = len(q)
        while edge:
            x, y, mins = q.popleft()
            if forest[y][x] == 'D':
                print(mins)
                return
            for ddx, ddy in zip(dx, dy):
                nx, ny = x + ddx, y + ddy
                if 0 <= nx < C and 0 <= ny < R:
                    if (forest[ny][nx] == '.' or forest[ny][nx] == 'D') and not visit[ny][nx]:
                        visit[ny][nx] = 1
                        q.append([nx, ny, mins+1])
            edge -= 1
    print("KAKTUS")
    return

input = sys.stdin.readline
R, C = map(int, input().split())
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
forest = []
q = deque(list())
water = deque(list())
visit = [[0]*C for _ in range(R)]
for r in range(R):
    forest.append(list(input().rstrip()))
    for c in range(C):
        if forest[r][c] == 'S':
            q.append([c, r, 0])
            visit[r][c] = 1
            forest[r][c] = '.'
        elif forest[r][c] == '*':
            water.append([c, r])
escape()

풀이 과정

풀이 시간 38분

백준 5427 불 문제랑 아주 유사한 문제다.

2022.02.07 - [코테 노트/백준] - 백준 5427 불 Python 3

 

백준 5427 불 Python 3

https://www.acmicpc.net/problem/5427 5427번: 불 상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로

hwayomingdlog.tistory.com

 

S에서 D로 가기 위해 한 칸씩 이동하는데 물이 있는 곳이나 곧 차오를 예정인 칸으로 이동은 불가하다는 것이 핵심이다.

즉, 매 분마다 물이 인접한 칸으로 차오르는 로직을 먼저 수행한 후에 고슴도치를 빈 곳으로 한 칸 이동시키면 된다.

이를 위해 물이 인접한 칸으로 번지는 BFS와 고슴도치를 이동시키는 BFS가 필요하다.

import sys
from collections import deque

def fill_up_water():
	#현 1분 동안 퍼뜨려야하는 물만 퍼뜨리기 위해 edge만큼 while문 반복
    edge = len(water)
    
    while edge:
        x, y = water.popleft()
        
        #인접한 4방향 탐색
        for ddx, ddy in zip(dx, dy):
            nx, ny = x+ddx, y+ddy
            #범위 안에 있으면서 빈 곳이라면 물을 퍼뜨린다
            if 0 <= nx < C and 0 <= ny < R and forest[ny][nx] == '.':
                forest[ny][nx] = '*'
                water.append([nx, ny])
        edge -= 1

def escape():
    while q:
    	#물을 퍼뜨린다
        fill_up_water()
		
        #현재 시간에 고슴도치의 가능한 위치들만 한 칸 이동시켜야 하므로 edge만큼만 while문 반복
        edge = len(q)
        while edge:
            x, y, mins = q.popleft()
            
            #비버의 굴에 도착한 경우, 함수 종료
            if forest[y][x] == 'D':
                print(mins)
                return
            
            #인접한 4방향 탐색
            for ddx, ddy in zip(dx, dy):
                nx, ny = x + ddx, y + ddy
                if 0 <= nx < C and 0 <= ny < R:
                	#비버의 굴이거나 빈 곳이면서 이전에 방문하지 않은 곳인 경우, 방문처리 후 큐에 담는다
                    if (forest[ny][nx] == '.' or forest[ny][nx] == 'D') and not visit[ny][nx]:
                        visit[ny][nx] = 1
                        q.append([nx, ny, mins+1])
            edge -= 1
    
    #while문이 정상 종료된 경우, 모든 칸을 탐색했지만 비버의 굴에 도착하지 못한 경우이므로 탈출 실패
    print("KAKTUS")
    return

input = sys.stdin.readline
R, C = map(int, input().split())

#좌, 상, 우, 하
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]

forest = []
#고슴도치의 위치와 이동한 시간을 담는 큐
q = deque(list())
#퍼뜨릴 물의 시발점을 담은 큐
water = deque(list())
visit = [[0]*C for _ in range(R)]

for r in range(R):
    forest.append(list(input().rstrip()))
    for c in range(C):
    	#고슴도치의 시작 위치와 0분을 q에 담고 방문처리 한다
        if forest[r][c] == 'S':
            q.append([c, r, 0])
            visit[r][c] = 1
            forest[r][c] = '.'
            
        #초기 물이 있는 위치를 water에 담는다
        elif forest[r][c] == '*':
            water.append([c, r])
escape()

#시간복잡도 = O(V+E), 공간복잡도 = O(n)

 

728x90
반응형

'코테 노트 > 백준' 카테고리의 다른 글

백준 16397 탈출 Python 3  (0) 2022.02.09
백준 2206 벽 부수고 이동하기 Python 3  (0) 2022.02.08
백준 5427 불 Python 3  (0) 2022.02.07
백준 9019 DSLR Python 3  (0) 2022.02.07
백준 6593 상범 빌딩 Python 3  (0) 2022.02.06