Skip to content

Commit 32698d2

Browse files
committed
[BOJ] 토마토 / 골드 5 / 85분
https://www.acmicpc.net/problem/7569
1 parent 825ebdd commit 32698d2

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
'''
2+
요구조건
3+
1. 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다.
4+
하나의 토마토에 인접한 곳은 위, 아래, 왼쪽, 오른쪽, 앞, 뒤 여섯 방향에 있는 토마토를 의미한다.
5+
6+
7+
2. 토마토가 모두 익을 때까지 최소 며칠이 걸리는지를 계산해서 출력해야 한다.
8+
만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고,
9+
토마토가 모두 익지는 못하는 상황이면 -1을 출력해야 한다.
10+
11+
1. 아이디어
12+
- 익은 토마토의 인접한 곳으로 그래프 탐색을 해야 하므로 bfs 사용.
13+
- 모든 토마토가 최소 몇 일에 익었는지 알기 위해서 토마토가 익은 일수를 저장해야 하므로 visited 배열에 저장.
14+
15+
2. 시간복잡도
16+
- BFS의 시간복잡도는 O(V+E) V는 최대 1,000,000, E는 최대 6,000,000. 1초 안에 가능
17+
18+
3. 구현
19+
3-1. 입력받기
20+
3-2. 초기 모든 토마토가 1 혹은 -1인지 확인.
21+
3-3. bfs 실행
22+
3-4. 모두 1이 아닌데 bfs가 끝나면 -1 반환, 모두 1이면 visited 배열 중 가장 큰 값(최소 일수) 출력.
23+
24+
'''
25+
26+
from collections import deque
27+
import sys
28+
29+
inp = sys.stdin.readline
30+
31+
# 가로, 세로, 높이
32+
N, M, H = map(int, inp().strip().split())
33+
34+
arr = []
35+
visited = [[[-1] * N for _ in range(M)] for _ in range(H)]
36+
37+
# 입력받기
38+
for _ in range(H):
39+
temp = []
40+
for _ in range(M):
41+
temp.append(list(map(int, inp().strip().split())))
42+
arr.append(temp)
43+
44+
flag = False
45+
# 초기 익은 토마토들을 저장하는 배열
46+
tomatoes = []
47+
48+
# 초기 모든 토마토가 1 혹은 -1인지 확인.
49+
for i in range(H):
50+
for j in range(M):
51+
for k in range(N):
52+
if arr[i][j][k] == 0:
53+
flag = True
54+
break
55+
if flag:
56+
break
57+
if flag:
58+
break
59+
60+
# 초기 1인 토마토 저장
61+
for i in range(H):
62+
for j in range(M):
63+
for k in range(N):
64+
if arr[i][j][k] == 1:
65+
tomatoes.append((i, j, k))
66+
visited[i][j][k] = 0
67+
68+
69+
def bfs(arr, visited, tomatoes):
70+
# 먼저 익은 토마토들로 큐 초기화
71+
queue = deque(tomatoes)
72+
73+
# 상 하 좌 우 위 아래
74+
dx = [-1, 1, 0, 0, 0, 0]
75+
dy = [0, 0, -1, 1, 0, 0]
76+
dz = [0, 0, 0, 0, -1, 1]
77+
78+
# bfs 탐색
79+
while queue:
80+
(z, y, x) = queue.popleft()
81+
for idx in range(6):
82+
# 인접 칸으로 이동
83+
new_z = z + dz[idx]
84+
new_y = y + dy[idx]
85+
new_x = x + dx[idx]
86+
87+
# 조건 확인(1. 인접칸의 인덱스가 범위 안인지, 2. 인접칸이 안익은 토마토인지, 3. 인접칸이 방문한적 없는지)
88+
if (0 <= new_x < N and 0 <= new_y < M and 0 <= new_z < H) and (arr[new_z][new_y][new_x] == 0) and \
89+
(visited[new_z][new_y][new_x] == -1):
90+
# 방문처리
91+
queue.append((new_z, new_y, new_x))
92+
arr[new_z][new_y][new_x] = 1
93+
visited[new_z][new_y][new_x] = visited[z][y][x] + 1
94+
95+
# bfs가 끝났을 때, arr 배열에 0이 하나라도 있으면 -1 출력, 그렇지 않으면 visited 배열 요소 중 가장 큰 값 출력
96+
if any(item == 0 for depth in arr for row in depth for item in row):
97+
print(-1)
98+
else:
99+
print(max(item for depth in visited for row in depth for item in row))
100+
101+
102+
if flag:
103+
bfs(arr, visited, tomatoes)
104+
else:
105+
print(0)

0 commit comments

Comments
 (0)