yha97 2022. 12. 4. 14:30

날짜 : 2022. 12. 04

사용 언어 : python

 

문제

 

 

코드

import sys
from collections import deque

m, n, h = map(int, sys.stdin.readline().split())  # 가로, 세로, 높이
box = list()
visited = [[[False] * m for _ in range(n)] for _ in range(h)]
q = deque()
for i in range(h):
    floor = list()
    for j in range(n):
        floor.append(list(map(int, sys.stdin.readline().split())))
    box.append(floor)


def bfs():  # 높이, 행, 열
    # 위, 아래, 우, 좌, 앞, 뒤
    dz = [1, -1, 0, 0, 0, 0]  # 높이
    dx = [0, 0, 1, -1, 0, 0]  # 행
    dy = [0, 0, 0, 0, 1, -1]  # 열
    while q:
        temp = q.popleft()
        for i in range(6):
            z = temp[0] + dz[i]
            x = temp[1] + dx[i]
            y = temp[2] + dy[i]
            if z in range(h) and x in range(n) and y in range(m):  # 범위에 있는 경우
                if box[z][x][y] == 0 and not visited[z][x][y]:  # 아직 안익은 토마토, 방문 x상태
                    box[z][x][y] = box[temp[0]][temp[1]][temp[2]] + 1  # 익음처리
                    q.append([z, x, y])

    return


for i in range(h):  # 높이
    for j in range(n):  # 행
        for k in range(m):  # 열
            if box[i][j][k] == 1 and not visited[i][j][k]:  # 익은 토마토인 경우
                #print(i, j, k)
                q.append([i, j, k])  # 마킹(for문으로 돌리는 경우 중복현상 발생)
                visited[i][j][k] = True
bfs()
res = 0
for i in range(h):
    for j in range(n):
        for k in range(m):
            res = max(box[i][j][k], res)
            if box[i][j][k] == 0:  # 안익은 토마토가 있는 경우
                print(-1)  # -1 출력 후 프로그램 종료
                exit()
print(res-1)
#print(box)

 

 

풀이

- 2차원 배열을 활용한 BFS 문제와 비슷한 유형이다.

- 반례의 경우

10 1 1

1 0 0 0 0 0 0 0 0 1

위처럼 나온다면 양끝에서 동시에 익기 시작해 결국 1 2 3 4 5 5 4 3 2 1 의 형태가 나와야 한다.

- 그렇지만 단순히 for 문을 돌리면서 BFS를 실행했을 때는 1 2 3 4 5 6 7 8 9 1 이 나오기 때문에 첫 for문을 통한 탐색에서는 방문하지 않았고 익은(값이 1) 토마토의 좌표만을 deque에 넣은 다음 이를 활용해서 BFS를 돌려야 한다.

- 그렇다면 위의 경우는 자연스럽게 맨 앞의 케이스를 한번 탐색하고 뒤의 케이스를 탐색한다.

- 그리고 마지막에는 기존 일수보다 1이 크기 때문에 그 값만 차감하여 출력한다.

 

알게된 점

- 토마토가 이미 익은 경우 더 빨리 익을 수 있을 때 이를 최신화하는 방식을 떠올리지 못했다.

- 기존문제에서의 풀이는 전부 맞았지만 질문글에서 찾은 위의 반례에서 계속 걸렸다.

- 그래서 풀이를 찾아보았고 위의 풀이를 알게 되었다.

- 지난번에도 DFS였나 BFS였나 문제에서 똑같이 틀린것 같은데 다음에는 똑같이 틀리지 않도록 이 문제는 꼭 기억해야겠다.

 

 

 

참고 사이트

- for문에서의 마킹 : https://velog.io/@falling_star3/백준Python-7569번-토마토

 

[백준][Python] 7569번 토마토

https://www.acmicpc.net/problem/7569▶ 해당 문제는 백준 7576번 토마토(2차원)의 의 3차원 문제이다. 철수의 토마토 농장에서는 토마토를 보관하는 큰 창고를 가지고 있다. 토마토는 아래의 그림과 같이

velog.io

- 3차원 배열 : https://dojang.io/mod/page/view.php?id=2297 

 

파이썬 코딩 도장: 23.6 연습문제: 3차원 리스트 만들기

다음 소스 코드를 완성하여 높이 2, 세로 크기 4, 가로 크기 3인 3차원 리스트를 만드세요(리스트 표현식 사용). practice_three_dimensional_list.py a = [                                  

dojang.io