N
: 세로 격자의 수 ()
M
: 가로 격자의 수 ()
N×M의 모눈종이 위에 아주 얇은 치즈 위치를 입력받아 이 치즈들이 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 출력하는 문제이다.
⌨️ 치즈가 녹는 규칙
- 4변 중 2변 이상이 외부와 접촉된 칸
- 1시간 후에 사라짐
- 치즈 내부 공간은 공기 접촉 ❌
- 모눈종이 위 치즈 위치
- 1 : 치즈 ⭕️
- 2 : 치즈 ❌
전체 모눈종이를 탐색하면서 치즈가 있는 경우를 찾아 4변 중 2변 이상 0으로 둘러싸여있는지 확인한다.
→ BFS를 활용한다!!
BFS
bfs 수행 →
치즈 녹이는 최대 시간 →
최종 시간복잡도
으로 최악의 경우 $O(t * 100^2)이 되어 1초 내에 수행할 수 있을 것이다.
치즈가 없을 때까지 bfs 반복
import sys
from collections import deque
input = sys.stdin.readline
# bfs 수행
def bfs():
# 큐 정의
queue = deque([(0, 0)])
# 방문 처리
visited[0][0] = 1
# 치즈 주변 공기 접촉 횟수 저장할 딕셔너리 정의
air = {}
while queue:
x, y = queue.popleft()
# 4가지 방향 확인
for i in range(4):
nx, ny = x + directions[i][0], y + directions[i][1]
if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny]:
# 치즈가 아닌 경우 찾기
if board[nx][ny] == 0:
visited[nx][ny] = 1
queue.append((nx, ny))
# 치즈인 경우 공기 접촉면 세기
else:
if (nx, ny) not in air:
air[(nx, ny)] = 1
else:
# 횟수 추가
air[(nx, ny)] += 1
return air
# N, M 입력
N, M = map(int, input().split())
# 치즈 정보 입력
board = [list(map(int, input().split())) for _ in range(N)]
# 4면 접근 방향
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
# 시간 초기화
t = 0
# 치즈가 다 없어질 때까지 bfs 반복
while True:
# 방문 리스트 정의
visited = [[0] * M for _ in range(N)]
air = bfs()
if not air: # 녹을 치즈가 없으면 종료
break
# 치즈 녹이기
for (x, y), count in air.items():
if count >= 2:
board[x][y] = 0
# 시간 추가
t += 1
# 결과 출력
print(t)