Skip to content

Commit 825ebdd

Browse files
committed
[BOJ] 토마토 / 골드 5 / 70분
https://www.acmicpc.net/problem/7576
1 parent 196c0a0 commit 825ebdd

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'''
2+
요구조건
3+
4+
1. 토마토는 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다.
5+
2. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익게 된다.(인접한 곳은 왼쪽, 오른쪽, 앞, 뒤를 의미한다)
6+
3. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다. 모든 토마토가 익을 수 없다면 -1을 출력한다.
7+
8+
1. 아이디어
9+
- 그래프를 탐색하여 최소 일수를 알아야 하므로 BFS
10+
- 각 토마토가 익는 일수는 인접한 토마토가 익은 일수 + 1이므로 visited 배열을 사용해 토마토가 익는 일 저장
11+
12+
2. 시간복잡도
13+
- 2 ≤ M,N ≤ 1,000
14+
- BFS의 시간복잡도는 O(V+E) V는 최대 1,000,000, E는 최대 4,000,000. 1초 안에 가능
15+
16+
3. 구현
17+
1. 입력받기
18+
2. 초기 모든 토마토가 1이거나 -1인지 확인하기
19+
3. bfs로 토마토 익히기 시뮬레이션
20+
4. 모두 1이 아닌데 bfs가 끝나면 -1 반환, 모두 1이면 visited 배열 중 가장 큰 값(최소 일수) 출력.
21+
'''
22+
23+
import sys
24+
from collections import deque
25+
26+
inp = sys.stdin.readline
27+
28+
M, N = map(int, inp().split())
29+
30+
arr = []
31+
visited = [[-1] * M for _ in range(N)]
32+
33+
for _ in range(N):
34+
arr.append(list(map(int, inp().split())))
35+
36+
37+
def find_tomato(arr, visited):
38+
tomatoes = []
39+
for i in range(N):
40+
for j in range(M):
41+
if arr[i][j] == 1:
42+
tomatoes.append((i, j))
43+
visited[i][j] = 0
44+
return tomatoes
45+
46+
47+
def bfs(arr, visited):
48+
dx = [1, -1, 0, 0]
49+
dy = [0, 0, 1, -1]
50+
51+
# 초기 설정
52+
queue = deque(find_tomato(arr, visited))
53+
54+
# BFS
55+
while queue:
56+
x, y = queue.popleft()
57+
for i in range(4):
58+
new_x = x + dx[i]
59+
new_y = y + dy[i]
60+
61+
# 상자 안이고, 0이고, 아직 방문하지 않았다면
62+
if 0 <= new_x < N and 0 <= new_y < M and arr[new_x][new_y] == 0 and visited[new_x][new_y] == -1:
63+
# 1로 바꾸고 방문처리하고 queue에 넣는다
64+
arr[new_x][new_y] = 1
65+
visited[new_x][new_y] = visited[x][y] + 1
66+
queue.append((new_x, new_y))
67+
68+
def check_tomatoes(arr):
69+
for i in range(N):
70+
for j in range(M):
71+
if arr[i][j] not in [-1, 1]:
72+
return True
73+
return False
74+
75+
# BFS가 끝난 후에 모두 1이 아니면 -1 반환, 모두 1이면 visited 중 가장 큰 값 찾기
76+
if check_tomatoes(arr):
77+
print(-1)
78+
else:
79+
print(max(map(max, visited)))
80+
81+
flag = False
82+
83+
# 초기에 모든 토마토가 1이거나 -1인지 확인하기
84+
for i in range(N):
85+
for j in range(M):
86+
if arr[i][j] == 0:
87+
flag = True
88+
break
89+
90+
if flag:
91+
bfs(arr, visited)
92+
else:
93+
print(0)
94+
95+

0 commit comments

Comments
 (0)