https://www.acmicpc.net/problem/2638
백준 2637 빙산 문제 처럼 몇번 닿았는지 카운트하고 조건에 만족했을 때 (2번 이상 닿았을때) 치즈를 녹이는 과정을 반복하려고 했다.
1. 무조건 외부 공기인 (0, 0)부터 덱에 넣어 외부 공기 탐색하며 외부 공기 표시(-1) 하기
2. 외부 공기 탐색 도중 치즈 (1)이 나오면 해당 구역 visited에 += 1
3. bfs 전부 탐색 후, visited가 2 이상인 부분 (외부공기가 두번 이상 닿은 부분) 치즈 녹이기
4. 치즈가 전부 녹을 때 까지 (녹이는 치즈가 없을 때 까지) 반복
# 성공 코드 1
# python 34976 KB 1176 ms
from collections import deque
N, M = map(int, input().split()) # 세로, 가로
mp = [list(map(int, input().split())) for _ in range(N)]
result = 0
all_melt = False
# 외부 공기에 닿은 치즈 녹이기
while not all_melt:
q = deque([(0, 0)])
visited = [[0] * M for _ in range(N)]
visited[0][0] = -1
# 외부 공기가 나오면 외부공기 체크(-1)하고, 치즈가 나오면 방문표시 (+= 1)
while q:
i, j = q.popleft()
for di, dj in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
ni, nj = i + di, j + dj
if 0 <= ni < N and 0 <= nj < M and visited[ni][nj] == 0 and mp[ni][nj] == 0:
visited[ni][nj] = -1
q.append((ni, nj))
elif 0 <= ni < N and 0 <= nj < M and mp[ni][nj] == 1:
visited[ni][nj] += 1
melted = False # 녹은 치즈가 있는지 체크
# 두번 이상 방문한 치즈 녹이기
for i in range(N):
for j in range(M):
if visited[i][j] >= 2:
mp[i][j] = 0
melted = True
# 녹은 부분이 없으면 모든 치즈가 다 녹음
if not melted:
all_melt = True
# 녹은부분 있으면 한시간 추가
else:
result += 1
print(result)
이렇게 하니까 되게 오래걸렸다.
그래서 방문 횟수만 추가하는게 아니라, 백준 2637 빙산 처럼 녹은 치즈를 배열로 관리하면서 체크하고 함수화했다.
1. 외부 공기 체크하는 함수 outside()
1-1. 배열에 치즈가 아니면 (!= 1) 외부공기 처리 후 덱에 추가
2. 치즈 녹이는 함수 melting()
2-1. 전체 배열을 순회하며 치즈인 부분이고, 주변에 외부공기가 (-1) 두번 이상이면 녹을 치즈 배열에 추가
2-2. 녹을 치즈 배열이 없으면 False return
2-3. 녹을 치즈 배열이 있으면 녹인 후 True return
3. 치즈가 전부 녹을 떄 까지 (melting 함수의 반환값이 False일 때 까지) 반복
# 성공 코드 2
# python 35000 KB 568 ms
from collections import deque
N, M = map(int, input().split()) # 세로, 가로
mp = [list(map(int, input().split())) for _ in range(N)]
# 외부 공기에 닿은 치즈 녹이기
def outside():
visited = [[False] * M for _ in range(N)]
visited[0][0] = True
mp[0][0] = -1
q = deque([(0, 0)])
while q:
i, j = q.popleft()
for di, dj in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
ni, nj = i + di, j + dj
if 0 <= ni < N and 0 <= nj < M and not visited[ni][nj] and mp[ni][nj] != 1:
mp[ni][nj] = -1
q.append((ni, nj))
visited[ni][nj] = True
def melting():
melting_cheese = []
for i in range(N):
for j in range(M):
if mp[i][j] == 1:
cnt = 0
for di, dj in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
ni, nj = i + di, j + dj
if 0 <= ni < N and 0 <= nj < M and mp[ni][nj] == -1:
cnt += 1
if cnt >= 2:
melting_cheese.append((i, j))
if not melting_cheese:
return False
for x, y in melting_cheese:
mp[x][y] = 0
return True
result = 0
while True:
outside()
if not melting():
break
result += 1
print(result)
'algorithm > BFS' 카테고리의 다른 글
[백준13460/골드1] 구슬 탈출 2 - Python (0) | 2025.04.23 |
---|---|
[백준19238/골드2] 스타트 택시 - Python (0) | 2025.03.19 |
[백준13913/골드4] 숨바꼭질 4 - Python (0) | 2025.02.17 |
[백준12851/골드4] 숨바꼭질 2 - Python (0) | 2025.02.15 |
[백준2573/골드4] 빙산 - Python (0) | 2025.01.28 |