이번 문제는 깊이우선탐색을 통해 해결하였다. 처음에는 치즈인 좌표에서 공기와 접촉한 면이 몇개인지 판단하고 지우는 방식으로 접근하였다. 그러나 이 경우, 하나의 좌표가 지워지면 다른 좌표에 영향을 줘서 결국 다른 방식으로 처리되었다. 그러던 중에 반대로 생각해보기로 하였다.
값이 0, 즉 좌표가 가리키는 값이 공기인 경우에는 방문처리를 한 후에 재귀호출하고, 가리키는 값이 치즈인 경우에는 값을 1 증가시킨다. 치즈의 값이 3 이상일 경우 공기와 닿는 면이 2개 이상이 된다. 한번의 깊이우선탐색을 진행 후에 3이상인 치즈를 0으로 바꿔주는 연산을 진행하게 되면 문제에서 요구하는 조건대로 치즈가 녹게 된다.
위의 그림은 예제에 대한 첫번째 깊이우선 탐색 후의 치즈이다. 3 이상이 된 츠즈들은 모두 0으로 갱신되게 된다.
y+dy[i]
로 저장한다.x+dx[i]
로 저장한다.visited[ny][nx]
가 False일 경우,cheese[ny][nx]
가 0이 아닐 경우, cheese[ny][nx]
를 1 증가시킨다.visited[ny][nx]
를 True로 갱신하고 dfs(ny, nx)
를 재귀호출한다.visited[0][0]
을 True로 갱신한다.dfs(0, 0)
을 호출한다.cheese[i][j]
가 3 이상일 경우, cheese[i][j]
를 0으로 갱신한다. (2개 이상의 변이 공기와 접촉된 치즈)cheese[i][j]
가 0보다 클 경우, cheese[i][j]
를 1로 갱신한다. ( 2개 미만의 변이 공기와 접촉된 치즈)import sys
sys.setrecursionlimit(10**9)
def dfs(y, x):
dy=[0, 0, -1, 1]
dx=[1, -1, 0, 0]
for i in range(4):
ny=y+dy[i]
nx=x+dx[i]
if ny>=0 and nx>=0 and ny<n and nx<m and visited[ny][nx]==False:
if cheese[ny][nx]!=0:
cheese[ny][nx]+=1
else:
visited[ny][nx]=True
dfs(ny, nx)
n, m=map(int, input().split())
cheese=[]
for _ in range(n):
cheese.append(list(map(int, input().split())))
answer=0
while True:
if cheese==[[0]*m for _ in range(n)]:
print(answer)
break
visited=[[False]*m for _ in range(n)]
visited[0][0]=True
dfs(0, 0)
for i in range(n):
for j in range(m):
if cheese[i][j]>=3:
cheese[i][j]=0
elif cheese[i][j]>0:
cheese[i][j]=1
answer+=1