알고리즘
[백준] 2573. 빙산 - python
hseoky
2024. 6. 24. 15:24
728x90
https://www.acmicpc.net/problem/2573
난이도: 골드4
알고리즘: BFS
풀이과정
빙산이 두 부분 혹은 그 이상으로 나누어지는 시점을 확인하는 문제다. BFS를 이용하면 이를 쉽게 확인할 수 있다.
먼저 입력의 크기를 살펴보면, 행 열을 나타내는 n과 m의 크기가 3 ~ 300 으로 시간 복잡도는 고려하지 않아도 된다.
반복문을 돌며 빙산이 나누어져 있는지 검사해야 한다. BFS를 활용하여, 0이 아닌 칸에서부터 상하좌우로 방문처리를 해준다. BFS를 적용한 후에 0이 아닌 칸이면서 방문처리가 되지 않은 칸이 있다면 나누어진 빙산이 있다는 뜻이므로, 걸린 시간을 출력하고 종료하면 된다.
빙산이 나누어지지 않고 전부 녹을 경우에는 0을 출력해야 하므로, 반복문을 돌며 모든 칸이 0이 되는 경우에는 반복을 종료하고 0을 출력한다.
소스코드
from collections import deque
from copy import deepcopy
def is_zero():
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] != 0:
return False
return True
def bfs():
global visited
for i in range(n):
for j in range(m):
if board[i][j] != 0:
visited[i][j] = 1
dq = deque()
dq.append((i, j))
while dq:
cur_y, cur_x = dq.popleft()
for i in range(4):
new_y = cur_y + dy[i]
new_x = cur_x + dx[i]
if 0 <= new_y < n and 0 <= new_x < m and board[new_y][new_x] != 0:
if not visited[new_y][new_x]:
visited[new_y][new_x] = 1
dq.append((new_y, new_x))
return
n, m = map(int, input().split())
board = []
answer = 0
for _ in range(n):
board.append(list(map(int, input().split())))
dy = [1, -1, 0, 0]
dx = [0, 0, 1, -1]
while not is_zero():
visited = [[0 for _ in range(m)] for _ in range(n)]
# bfs 1번 수행
bfs()
# 빙산이 나누어졌다면 종료
for i in range(n):
for j in range(m):
if board[i][j] != 0 and not visited[i][j]:
print(answer)
exit()
new_board = deepcopy(board)
# 빙산 녹이기
for i in range(n):
for j in range(m):
if board[i][j] != 0:
for k in range(4):
ny = i + dy[k]
nx = j + dx[k]
if 0 <= ny < n and 0 <= nx < m and board[ny][nx] == 0:
if new_board[i][j] > 1:
new_board[i][j] -= 1
else:
new_board[i][j] = 0
board = new_board
answer += 1
print(0)
시행착오
빙산 녹이기를 수행할 때, 직접 board에 값을 갱신하면 다음 갱신에 영향을 줄 수 있으므로 new_board를 할당해 주어야 한다.
728x90