Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

개발하지연

[백준 7576번] 토마토 (python) 본문

알고리즘

[백준 7576번] 토마토 (python)

JeongJiyeon 2021. 8. 26. 14:50

문제

철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다.

창고에 보관되는 토마토들 중에는 잘 익은 것도 있지만, 아직 익지 않은 토마토들도 있을 수 있다. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. 하나의 토마토의 인접한 곳은 왼쪽, 오른쪽, 앞, 뒤 네 방향에 있는 토마토를 의미한다. 대각선 방향에 있는 토마토들에게는 영향을 주지 못하며, 토마토가 혼자 저절로 익는 경우는 없다고 가정한다. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다.

토마토를 창고에 보관하는 격자모양의 상자들의 크기와 익은 토마토들과 익지 않은 토마토들의 정보가 주어졌을 때, 며칠이 지나면 토마토들이 모두 익는지, 그 최소 일수를 구하는 프로그램을 작성하라. 단, 상자의 일부 칸에는 토마토가 들어있지 않을 수도 있다.

 

기록

(graph 3일차) 다른 문제랑 이름이 같아서 한 번 잘못 제출했다..ㅎㅎ

 

최단 거리를 구하는 문제와 비슷한 종류이기 때문에 bfs를 사용했다. 익은 토마토에서 한 칸씩 이동하며 count를 세고, 더 이상 채울 수 없을 때까지 이동해서 최종 count를 출력한다. 출발지가 하나가 아니었기 때문에 배열을 두 개 사용하여 현재 단계와 다음 단계에 이동할 토마토 칸을 따로 저장하였다. 현재 단계의 토마토를 다 방문하면 다음 단계의 토마토를 현재 단계의 배열로 옮겨 다음 단계의 토마토를 추가하는 과정을 반복한다.

 

토마토가 다 익었는지 확인을 어떻게 할까를 고민하다가, count를 저장하고 나중에 확인하는 것보다 미리 개수를 저장해놓는 것이 효율적이라고 생각했다. 그래서 total 변수에 현재 토마토의 개수를 저장하고 토마토를 방문할 때마다 1씩 줄여가며 최종 개수를 확인하여 답을 도출하는 방법으로 구현했다. 

 

코드

from collections import deque

m, n = map(int, input().split())
board = [list(map(int, input().split())) for i in range(n)]
tomatoes = []
total = m*n
for i in range(n):
    for j in range(m):
        if board[i][j]==1 : tomatoes.append((i, j))
        if board[i][j]==-1 : total -= 1

visit = [[0]*m for i in range(n)]
cnt = -1
for i, j in tomatoes : visit[i][j] = 1
while tomatoes:
    cnt+=1
    temp = tomatoes.copy()
    tomatoes = []
    while temp:
        y, x = temp.pop()
        total -= 1
        for i, j in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
            if y+i>=0 and y+i<n and x+j>=0 and x+j<m :
                if visit[y+i][x+j]==0 and board[y+i][x+j]==0:
                    tomatoes.append((y+i, x+j))
                    visit[y+i][x+j] = 1

if total : print(-1)
else : print(cnt)

1. 변수와 토마토 정보 저장, 익은 토마토(출발지점)의 위치정보 저장, 최종 토마토 개수를 확인할 total 변수를 전체 칸 개수에서 -1 칸 개수를 뺀 값으로 초기화한다.

2. 방문여부 저장할 배열과 최소 일 수를 저장할 cnt 변수를 초기화한다.

3. temp 배열에서 현재 익은 토마토들을 모두 꺼내 현재 토마토의 상하좌우 칸을 tomatoes 배열에 저장한다. temp에서 현재 익은 토마토들을 모두 꺼내면 다음 이동할 토마토들을 temp에 넣어 이 과정을 반복한다. (방문 할 때마다 total-1, 다음 단계로 이동할 때마다 cnt+1)

4. tomatoes 배열에 다음 이동할 토마토가 없다면 과정을 끝내고 total(남은 토마토 개수)이 있다면 -1, 없다면 cnt 변수를 출력한다.

Comments