본문 바로가기

알고리즘/🥇 골드

백준 7569 토마토 파이썬 풀이

728x90

난이도 : 골드5
풀이일 : 04171
https://www.acmicpc.net/problem/7569

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net


링크로 이동하기 귀찮은 분들을 위한 문제 캡쳐


풀이 과정
- 익은 토마토는 동, 서, 남, 북, 상, 하 6방향 토마토에 영향
- 3차원 형식으로 리스트 구성 -> 6방향 탐색 진행
- 포인터 사용으로 pop 연산 시간초과 방지
- 익은 토마토 리스트를 구성해 토마토 숙성 함수에 넘겨주기
- 토마토가 익는 날짜는 이전 숫자 +1 기록 -> 최종 정답은 최고값 -1


풀이 코드

import sys

def find(arr):
    tomato = []    # 익은 토마토 좌표 기록
    for x in range(h):
        for y in range(n):
            for z in range(m):
                if arr[x][y][z] == 1:
                    tomato.append([x, y, z])
    red(tomato)    # 토마토 숙성
    day = 0
    # 전체 숙성 여부, 날짜 확인
    for x in range(h):
        for y in range(n):
            for z in range(m):
                if arr[x][y][z] == 0:
                    return print(-1)    # 안익은 토마토 있을 경우
                if arr[x][y][z] > day:
                    day = arr[x][y][z]
    return print(day-1)    # 모든 토마토가 익었을 경우

# 토마토 익히기 함수
def red(queue):
    p = 0    # 포인터 접근
    while p < len(queue):    # 포인터가 큐 길이보다 짧은 동안 진행
        i, j, k = queue[p][0], queue[p][1], queue[p][2]
        p += 1
        di = [-1, 1, 0, 0, 0, 0]    # 여섯 방향 탐색
        dj = [0, 0, -1, 1, 0, 0]
        dk = [0, 0, 0, 0, -1, 1]
        for l in range(6):
            ni, nj, nk = i + di[l], j + dj[l], k + dk[l]
            if 0 <= ni < h and 0 <= nj < n and 0 <= nk < m:
                if box[ni][nj][nk] == 0:
                    box[ni][nj][nk] = box[i][j][k] + 1
                    queue.append([ni, nj, nk])
    return


m, n, h = list(map(int, sys.stdin.readline().split()))

box = []

for _ in range(h):
    tmp = [list(map(int, sys.stdin.readline().split())) for _ in range(n)]
    box.append(tmp)

find(box)

느낀점
3차원으로 데이터를 입력받고, 조회하는 코드는 처음 짜봐서 재미있었다.
또, 로직을 정리하고 그대로 코딩한 뒤 문제를 맞았을 때가 확실히 기분이 제일 좋다.
나연님은 다르게 풀었던데 다른 사람들의 코드를 구경하면서 비교해보는 과정도 늘 재밌다.