|
3 | 3 | https://www.acmicpc.net/problem/7569 |
4 | 4 | 유형: Graph, BFS |
5 | 5 | """ |
6 | | -# PR 올릴 때 공개 예정 |
| 6 | + |
| 7 | +""" |
| 8 | +풀이1 |
| 9 | +""" |
| 10 | +import sys |
| 11 | +from collections import deque |
| 12 | +input = sys.stdin.readline |
| 13 | + |
| 14 | +# 1. 입력 처리 |
| 15 | +M, N, H = map(int, input().split()) # 가로, 세로, 높이 |
| 16 | +box = [[list(map(int, input().split())) for _ in range(N)] for _ in range(H)] |
| 17 | + |
| 18 | +# 2. 초기 변수 설정 |
| 19 | +queue = deque([]) |
| 20 | +directions = [(-1, 0, 0), (0, 1, 0), (1, 0, 0), (0, -1, 0), |
| 21 | + (0, 0, 1), (0, 0, -1)] # 위-오른쪽-아래-왼쪽-앞-뒤 |
| 22 | +day = 0 # 정답으로 반환할 변수 |
| 23 | + |
| 24 | +# 3. 초기 익은 토마토를 큐에 추가하기 |
| 25 | +for i in range(H): |
| 26 | + for j in range(N): |
| 27 | + for k in range(M): |
| 28 | + if box[i][j][k] == 1: |
| 29 | + queue.append((i, j, k)) |
| 30 | + |
| 31 | +# 4. BFS 탐색 |
| 32 | +while queue: |
| 33 | + z, y, x = queue.popleft() |
| 34 | + |
| 35 | + for dx, dy, dz in directions: |
| 36 | + nx, ny, nz = x + dx, y + dy, z + dz |
| 37 | + # 범위 내에 있고 아직 안 익은 토마토라면 |
| 38 | + if (0 <= nx < M and 0 <= ny < N and 0 <= nz < H) and (box[nz][ny][nx] == 0): |
| 39 | + box[nz][ny][nx] += box[z][y][x] + 1 # 익은 날짜 누적 갱신 |
| 40 | + queue.append((nz, ny, nx)) |
| 41 | + |
| 42 | +# 5. 정답 구하기 |
| 43 | +for height in box: |
| 44 | + for row in height: |
| 45 | + for tomato in row: |
| 46 | + # 안 익은 토마토가 남아있는지 여부 확인 |
| 47 | + if tomato == 0: |
| 48 | + print(-1) |
| 49 | + exit() |
| 50 | + # 익는데 걸린 최대 일수 추적 |
| 51 | + day = max(day, max(row)) |
| 52 | + |
| 53 | +# 6. 정답 출력 |
| 54 | +print(day - 1) |
| 55 | + |
| 56 | + |
| 57 | +""" |
| 58 | +풀이2 |
| 59 | +""" |
| 60 | +import sys |
| 61 | +from collections import deque |
| 62 | + |
| 63 | +input = sys.stdin.readline |
| 64 | + |
| 65 | +# 상자의 가로 m, 세로 n, 높이 h |
| 66 | +m, n, h = map(int, input().split()) |
| 67 | +tomatoes = [] |
| 68 | + |
| 69 | +for _ in range(h): |
| 70 | + layer = [list(map(int, input().split())) for _ in range(n)] |
| 71 | + tomatoes.append(layer) |
| 72 | + |
| 73 | +directions = [(0, 0, 1), (0, 0, -1), (0, -1, 0), (0, 1, 0), (1, 0, 0), (-1, 0, 0)] # 상하좌우앞뒤 |
| 74 | + |
| 75 | +def bfs(): |
| 76 | + |
| 77 | + queue = deque() # (층, 행, 열, 일수) |
| 78 | + |
| 79 | + # 초기 익은 토마토 위치 큐에 추가 |
| 80 | + for z in range(h): |
| 81 | + for x in range(n): |
| 82 | + for y in range(m): |
| 83 | + if tomatoes[z][x][y] == 1: |
| 84 | + queue.append((z, x, y, 0)) # (층, 행, 열, 일수) |
| 85 | + |
| 86 | + max_day = 0 # 익는 데 걸린 최대 일수 추적 |
| 87 | + |
| 88 | + while queue: |
| 89 | + z, x, y, day = queue.popleft() |
| 90 | + max_day = max(max_day, day) # 가장 오래 걸린 일수 갱신 |
| 91 | + |
| 92 | + for dz, dx, dy in directions: |
| 93 | + nz, nx, ny = z + dz, x + dx, y + dy |
| 94 | + if 0 <= nz < h and 0 <= nx < n and 0 <= ny < m: |
| 95 | + if tomatoes[nz][nx][ny] == 0: # 익지 않은 토마토일 때 |
| 96 | + tomatoes[nz][nx][ny] = 1 |
| 97 | + queue.append((nz, nx, ny, day + 1)) # 익는 데 하루 추가 |
| 98 | + |
| 99 | + |
| 100 | + return max_day |
| 101 | + |
| 102 | +def all_ripe(): |
| 103 | + # 모든 토마토가 익었는지 확인 |
| 104 | + for i in range(h): |
| 105 | + for j in range(n): |
| 106 | + for k in range(m): |
| 107 | + if tomatoes[i][j][k] == 0: |
| 108 | + return False |
| 109 | + return True |
| 110 | + |
| 111 | +''' |
| 112 | +1: 익은 토마토 |
| 113 | +0: 익지 않은 토마토 |
| 114 | +-1: 토마토가 없음 |
| 115 | +''' |
| 116 | +# 초기 상태 확인 |
| 117 | +if all_ripe(): |
| 118 | + print(0) |
| 119 | + exit(0) |
| 120 | +else: |
| 121 | + days = bfs() |
| 122 | + |
| 123 | + # 모든 토마토가 익었는지 다시 확인 |
| 124 | + if all_ripe(): |
| 125 | + print(days) |
| 126 | + else: |
| 127 | + print(-1) |
| 128 | + |
0 commit comments