solved_ac[Class4][치즈](https://www.acmicpc.net/problem/2638)
<그림 1>
N×M의 모눈종이 위에 아주 얇은 치즈가 <그림 1>과 같이 표시되어 있다. 단, N 은 세로 격자의 수이고, M 은 가로 격자의 수이다. 이 치즈는 냉동 보관을 해야만 하는데 실내온도에 내어놓으면 공기와 접촉하여 천천히 녹는다. 그런데 이러한 모눈종이 모양의 치즈에서 각 치즈 격자(작 은 정사각형 모양)의 4변 중에서 적어도 2변 이상이 실내온도의 공기와 접촉한 것은 정확히 한시간만에 녹아 없어져 버린다. 따라서 아래 <그림 1> 모양과 같은 치즈(회색으로 표시된 부분)라면 C로 표시된 모든 치즈 격자는 한 시간 후에 사라진다.
<그림 2>
<그림 3>
<그림 2>와 같이 치즈 내부에 있는 공간은 치즈 외부 공기와 접촉하지 않는 것으로 가정한다. 그러므 로 이 공간에 접촉한 치즈 격자는 녹지 않고 C로 표시된 치즈 격자만 사라진다. 그러나 한 시간 후, 이 공간으로 외부공기가 유입되면 <그림 3>에서와 같이 C로 표시된 치즈 격자들이 사라지게 된다.
모눈종이의 맨 가장자리에는 치즈가 놓이지 않는 것으로 가정한다. 입력으로 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 구하는 프로그램을 작성하시오.
첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로 표시된다. 또한, 각 0과 1은 하나의 공백으로 분리되어 있다.
출력으로는 주어진 치즈가 모두 녹아 없어지는데 걸리는 정확한 시간을 정수로 첫 줄에 출력한다.
8 9
0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0
0 0 0 1 1 0 1 1 0
0 0 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0
0 0 1 1 0 1 1 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
4
설명하기에 앞서 나는 기본 BFS 틀에 조건만 추가하여 풀었다.
벽 부수고 이동하기와 비슷한 결의 문제이다.
예제를 시간의 경과에 따라 나타내보았다.
(0,0) 초록색 형광펜 지점을 시작 노드로 설정하였다. 치즈에 표기되어 있는 파란색 숫자는 치즈가 몇 개의 외부 공기에 맞닿아 있는지를 의미한다.
즉, 외부 공기(0) 기준으로 상하좌우 탐색을 하며 치즈(1)를 만날 때마다 터치 카운트를 증가시킨다.
그렇게 했을 때, 외부 공기의 터치 카운트가 2번 이상된 치즈만 골라서 녹인다(1을 0으로 바꾼다.)
출발 노드에서 BFS를 돌린 다음에 더 이상 남아있는 치즈가 없을 때까지 BFS를 반복한다.
동시에 BFS를 한 번 돌릴 때마다 시간을 증가시켜주면(hour += 1) 최종적인 치즈가 녹는 시간을 구할 수 있다.
from collections import deque
N,M = map(int,input().split())
cheese = []
for _ in range(N):
cheese.append(list(map(int,input().split())))
dx = [1,-1,0,0]
dy = [0,0,1,-1]
def bfs(a,b):
q = deque([(a,b)])
visited = [[0]*M for _ in range(N)]
touch = [[0]*M for _ in range(N)]
while q:
x,y = q.popleft()
for i in range(4):
nx = x+dx[i]
ny = y+dy[i]
if 0<=nx<N and 0<=ny<M and visited[nx][ny] == 0:
if cheese[nx][ny] == 0:
q.append((nx,ny))
visited[nx][ny] = 1
if cheese[nx][ny] == 1:
touch[nx][ny] += 1
for i in range(N):
for j in range(M):
if touch[i][j] >= 2:
cheese[i][j] = 0
def empty_check(cheese):
for i in range(N):
for j in range(M):
if cheese[i][j] == 1:
return False
return True
hour = 0
while True:
if empty_check(cheese):
print(hour)
break
bfs(0,0)
hour += 1