https://www.acmicpc.net/problem/2638
2638번: 치즈
첫째 줄에는 모눈종이의 크기를 나타내는 두 개의 정수 N, M (5 ≤ N, M ≤ 100)이 주어진다. 그 다음 N개의 줄에는 모눈종이 위의 격자에 치즈가 있는 부분은 1로 표시되고, 치즈가 없는 부분은 0으로
www.acmicpc.net
백준 - 치즈 (2638번)
난이도 : Gold 3
알고리즘 : Simulation & Implementation (구현), BFS or DFS
import sys
input = sys.stdin.readline
def adjs_conds(r, c):
if 0 < r: yield r-1, c
if r < N-1: yield r+1, c
if 0 < c: yield r, c-1
if c < M-1: yield r, c+1
def adjs(r, c):
yield r-1, c
yield r+1, c
yield r, c+1
yield r, c-1
def update_board(cands):
while cands:
r, c = cands.pop()
for rr, cc in adjs(r, c):
if board[rr][cc]:
continue
board[rr][cc] = 2
cands.append((rr, cc))
def find_chz_melts():
cands = []
for r in range(N):
for c in range(M):
if board[r][c] != 1:
continue
if 2 <= sum(1 for rr, cc in adjs(r, c) if board[rr][cc] == 2):
cands.append((r, c))
for r, c in cands:
board[r][c] = 2
return cands
if __name__ == '__main__':
N, M = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)]
board[0][0] = 2
cands = [(0, 0)]
while cands:
r, c = cands.pop()
for rr, cc in adjs_conds(r, c):
if board[rr][cc]:
continue
board[rr][cc] = 2
cands.append((rr, cc))
cnt = 0
while True:
cands = find_chz_melts()
if cands:
cnt += 1
else:
break
update_board(cands)
print(cnt)
전형적인 구현 문제이다.
외부 공기와 내부 공기를 구분하는 것이 핵심이다.
dfs를 활용해서 (bfs도 상관 없다.)
외부 공기는 2로, 내부 공기는 0으로 표시해주었다.
①. find_chz_melts 함수를 통해
치즈 1의 상하좌우 중,
외부 공기 2가 2개 이상이라면 녹는 것으로 구현했다.
②. 그리고 녹는 치즈가 생기면,
기존의 내부 공기 0이 새로운 외부 공기 2가 될 수 있기 때문에
update_board 함수로 이 부분을 구현했다.
위의 ①과 ② 과정을 모든 치즈가 녹을 때까지 반복하면서,
반복 횟수를 세고 반환한다.
'Algorithm' 카테고리의 다른 글
과제 진행하기 (176962번) - 프로그래머스 (Programmers) (0) | 2023.06.07 |
---|---|
도서관 (1461번) - 백준 (BOJ) (0) | 2023.06.06 |
ACM Craft (1005번) - 백준 (BOJ) (0) | 2023.06.05 |
교환 (1039번) - 백준 (BOJ) (0) | 2023.06.03 |
연속된 부분 수열의 합 (178870번) - 프로그래머스 (Programmers) (0) | 2023.06.02 |