BOJ 2636번 치즈 Python 문제 풀이
분류: Graph Traversal (그래프 탐색), bfs
https://www.acmicpc.net/problem/2636
from sys import stdin
from collections import deque
from typing import List
def bfs(row: int, col: int, board: List[List[int]]) -> int:
dy = [1, -1, 0, 0]
dx = [0, 0, 1, -1]
visit = list([False] * col for _ in range(row))
dq = deque([(0, 0)])
visit[0][0] = True
cnt = 0
while dq:
cy, cx = dq.popleft()
for i in range(4):
ny, nx = cy + dy[i], cx + dx[i]
if 0 <= ny < row and 0 <= nx < col and not visit[ny][nx]:
if board[ny][nx] == 0:
dq.append((ny, nx))
elif board[ny][nx] == 1:
board[ny][nx] = 0
cnt += 1
visit[ny][nx] = True
return cnt
def main():
def input():
return stdin.readline().rstrip()
row, col = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(row)]
time, cnts = 0, {}
while True:
cnts[time] = bfs(row, col, board)
if cnts[time] == 0:
break
time += 1
print(time)
print(cnts[time - 1])
if __name__ == "__main__":
main()
매 시간마다 좌표 (0, 0)에서부터 BFS 탐색을 통해 바깥 공기과 녹는 치즈를 확인한다. 탐색 과정에서 바깥 공기를 만나면 deque dq
에 저장하고, 치즈를 만나면, 값을 0으로 바꾸고 cnt
변수에 1을 더한다. 그리고 탐색한 자리는 visit
값을 True로 변경하여, 중복되지 않게 한다. 이 과정을 치즈가 다 녹을 때까지 반복하여 답을 구한다.
from sys import stdin
from collections import deque
from typing import List
board = []
row, col = 0, 0
dy = [1, -1, 0, 0]
dx = [0, 0, 1, -1]
def bfs(y: int, x: int, visit: List[List[bool]]) -> deque[(int, int)]:
if visit[y][x]:
return deque()
dq = deque([(y, x)])
board[y][x] = -1
visit[y][x] = True
melted = deque()
while dq:
cy, cx = dq.popleft()
for i in range(4):
ny, nx = cy + dy[i], cx + dx[i]
if 0 <= ny < row and 0 <= nx < col and not visit[ny][nx]:
if board[ny][nx] == 0:
board[ny][nx] = -1
dq.append((ny, nx))
elif board[ny][nx] == 1:
board[ny][nx] = 0
melted.append((ny, nx))
visit[ny][nx] = True
return melted
def main():
def input():
return stdin.readline().rstrip()
global board, row, col
row, col = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(row)]
time, cnts = -1, {}
air = deque([(0, 0)])
while True:
visit = list([False] * col for _ in range(row))
cnt = len(air)
if cnt == 0:
break
cnts[time] = cnt
for _ in range(cnt):
y, x = air.popleft()
air += bfs(y, x, visit)
time += 1
print(time)
print(cnts[time - 1])
if __name__ == "__main__":
main()
이전 풀이에서는 매번 좌표 (0, 0) 위치에서부터 bfs 탐색을 하기 때문에 이전에 이미 공기가 된 위치도 반복해서 탐색한다. 따라서 이번 풀이에서는 치즈가 녹아 새롭게 공기가 된 위치를 deque air
에 저장하여, 해당 위치에서부터 bfs 탐색을 진행한다.
채점 결과 수행 시간이 줄긴 했지만, 이전과 많이 차이나지는 않는다.