728x90
문제 보기
[사용한 알고리즘]
BFS(너비 우선 탐색), 구현
[문제 접근]
세 단계 과정을 통해 문제를 구현하고자 하였습니다. 첫째, 주어진 N x M 모눈종이에서 외부 공기 위치를 구합니다. 둘째, 각 치즈 상, 하, 좌, 우에 인접한 외부 공기 위치 개수를 파악합니다. 셋째, 외부 공기가 2개 이상인 치즈를 녹입니다. 위 과정을 모든 치즈가 녹을 때까지 진행합니다.
[알고리즘]
1. 외부 공기 위치를 구합니다. (맨 가장자리를 출발점으로 BFS 탐색을 하여 외부 공기를 파악합니다)
2. 각 치즈의 인접한 외부 공기 위치 개수를 구합니다.
3. 외부 공기가 2개 이상인 치즈를 녹입니다.
4. 위 과정을 모든 치즈가 녹을 때까지 반복합니다.
[코드]
from collections import deque
import sys
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def outer(r, c, visited):
q = deque()
q.append((r, c))
while q:
x, y = q.popleft()
visited.add((x, y))
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
if 0 <= nx < n and 0 <= ny < m:
if maps[nx][ny] != 1 and (nx, ny) not in visited:
visited.add((nx, ny))
q.append((nx, ny))
if __name__ == "__main__":
n, m = map(int, sys.stdin.readline().split())
maps = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]
t = 0
while True:
# 외부 공기 구별
visited = set()
for i in range(n):
if maps[i][0] != 1:
outer(i, 0, visited)
for i in range(n):
if maps[i][m - 1] != 1:
outer(i, m - 1, visited)
for i in range(m):
if maps[0][i] != 1:
outer(0, i, visited)
for i in range(m):
if maps[n - 1][i] != 1:
outer(n - 1, i, visited)
for i, j in visited:
maps[i][j] = 2
cnt = 0 # 치즈 개수
for i in range(n):
for j in range(m):
# 가장 자리 제외
if (i == 0 and j == 0) or (i == 0 and j == m - 1) or (i == n - 1 and j == 0) or (
i == n - 1 and j == m - 1) or maps[i][j] != 1:
continue
cnt += 1
outer_cnt = 0
# 외부 공기 개수 파악(상, 하, 좌, 우)
if i - 1 >= 0 and maps[i - 1][j] == 2: # 상
outer_cnt += 1
if i + 1 < n and maps[i + 1][j] == 2: # 하
outer_cnt += 1
if j - 1 >= 0 and maps[i][j - 1] == 2: # 좌
outer_cnt += 1
if j + 1 < m and maps[i][j + 1] == 2: # 우
outer_cnt += 1
if outer_cnt >= 2:
maps[i][j] = 0 # 치즈 제거
if cnt == 0:
break
t += 1
print(t)
728x90
'알고리즘 풀이 > 백준' 카테고리의 다른 글
[백준 1744] 수 묶기 - Python (0) | 2020.12.10 |
---|---|
[백준 1111] IQ Test (2) | 2020.12.05 |
[백준 18809] Gaaaaaaaaaarden - Python (0) | 2020.11.25 |
[ 백준 1707 ] 이분 그래프 - Python (0) | 2020.11.24 |
[ 백준 1339 ] 단어 수학 - Python (0) | 2020.11.23 |