[백준] 7569 : 토마토
문제
https://www.acmicpc.net/problem/7569
고민했던 부분
-
1인 노드들을 어떻게 한번에 가져가서 동서남북상하를 봐줘야 하는 건지 고민했음
-> 처음에 입력받았을 때 1인 것의 좌표를 넣는 리스트에 1 값을 가진 것들의 좌표를 모두 넣어줌!
그리고 bfs가 한 번 돌고 난 이후엔 변경된 값들을 담은 리스트를 매개변수로 해서 bfs를 계속 돌려줌! -
결과 : 시간 초과(Python), 메모리 초과(PyPy)
-
개선해야 하는 부분 : 어떻게 1을 한번에 넣어주고 queue에 더이상 값이 없을 때까지 bfs를 돌려줄 수 있을까??
-
해결책
queue
에 모든 것들을 담아서 처리해준다
-> 토마토들을 입력받을 때 아예 1인 것들은 좌표값을 queue
에 append
해줌!
-> 그리고 나중에 변해야 하는 것들은 queue
에 또 append
해줌!
-> 결과적으로 queue
엔 1인 좌표 값들이 먼저 pop
으로 처리되면서 계속 변해야 하는 부분이 뒤에 쌓이는 구조가 됨
-> 1인 좌표 값이 먼저 그래프를 변화시키고, 그 다음에 변화되어야 하는 부분이 기준이 되어야 하므로 그 다음에 큐에서 처리되는 구조!
시간초과 풀이
from collections import deque
import sys
input = sys.stdin.readline
# 의문 1. visited 처리를 해줘야 하나? - no no
M, N, H = map(int, input().split())
box = [[[0 for _ in range(M)] for _ in range(N)] for _ in range(H)]
# 좌표 이동
dx = [-1, +1, 0, 0, 0, 0]
dy = [0, 0, -1, +1, 0 ,0]
dz = [0, 0, 0, 0, -1, +1]
ok = 0 # 익은 토마토 개수 1
notyet = 0 # 익지 않은 토마토 개수 0
nothing = 0 # 아무것도 없는 토마토 개수 -1
onelist = []
for i in range(H):
for j in range(N):
num = list(map(int, input().split()))
ok += num.count(1)
notyet += num.count(0)
nothing += num.count(-1)
box[i][j] = num
total = M * N * H
# 저장될 때부터 모든 토마토가 익어있는 상태인 경우 0 출력
if total == (ok + nothing):
print(0)
exit(0)
# 1인 것의 좌표를 넣는 리스트
onelist = []
for a in range(H):
for b in range(N):
for c in range(M):
if box[a][b][c] == 1:
onelist.append((a, b, c))
# BFS 함수
def bfs(onelist):
queue = deque()
# 1로 만들어줘야 하는 좌표 리스트
clist = []
for d, e, f in onelist: # 1인 것들의 좌표
queue.append((d, e, f))
while queue:
z, y, x = queue.popleft()
exist = box[z][y][x]
for k in range(6):
p, l, m = z + dz[k], y + dy[k], x + dx[k] # 이동했을 때 좌표 (층 H, 열 N, 행 M)
if 0 <= p <= H-1 and 0 <= l <= N-1 and 0 <= m <= M-1: # 범위 안에 들 때
if box[p][l][m] == 0:
clist.append((p, l, m))
for q, w, e in clist:
box[q][w][e] = exist + 1
if len(clist) == 0:
print(-1)
exit(0)
for g in range(H):
for h in range(N):
if box[g][h].count(0) >= 1:
bfs(clist)
# 1인 좌표의 리스트를 넣고 너비 우선 탐색
bfs(onelist)
maxNum = -1
for a in range(H):
for b in range(N):
for c in range(M):
maxNum = max(maxNum, box[a][b][c])
print(maxNum-1)
제대로 된 풀이
import sys
from collections import deque
M,N,H = map(int,input().split()) # mn크기, h상자수
queue = deque([])
graph = []
for i in range(H):
tmp = []
for j in range(N):
tmp.append(list(map(int,sys.stdin.readline().split())))
for k in range(M):
if tmp[j][k]==1:
queue.append([i,j,k]) # 큐에 1인 것들을 넣어주면 먼저 처리됨!
graph.append(tmp)
dx = [-1,1,0,0,0,0]
dy = [0,0,1,-1,0,0]
dz = [0,0,0,0,1,-1]
while(queue):
x,y,z = queue.popleft()
for i in range(6):
a = x+dx[i]
b = y+dy[i]
c = z+dz[i]
if 0<=a<H and 0<=b<N and 0<=c<M and graph[a][b][c]==0:
queue.append([a,b,c])
graph[a][b][c] = graph[x][y][z]+1 # 원래 1이었던 애들 주변을 2로만든다. 2었던 애들이 0인 애들을 익게하면 3으로만들고...
day = 0
for i in graph: # level
for j in i: # row
for k in j: # column
if k==0:
print(-1) # while문이 끝나도 0인애가 있다면 -1 출력
exit(0)
day = max(day,max(j)) # 가장 나중에 익은 과일의 수를 불러옴
print(day-1)
Author And Source
이 문제에 관하여([백준] 7569 : 토마토), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@letsbebrave/백준-7569-토마토저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)