Algorithm(BOJ, Python)/BFS&DFS
[백준_7569] 토마토 python
kurooru
2022. 8. 22. 11:28
3차원 배열만 잘 구현할 수 있다면,
어렵지 않게 해결할 수 있는 문제였다.
# m, n, h 입력
m, n, h = map(int, input().split())
# storage 설계
storage = []
# 각 층 입력
for _ in range(h):
floor = [
list(map(int, input().split()))
for _ in range(n)
]
storage.append(floor)
# 함수들
# in_range(f, x, y)
def in_range(f, x, y):
return 0 <= f and f < h and 0 <= x and x < n and 0 <= y and y < m
# check(f, x, y)
def check(f, x, y):
# 범위 안에 있고, 안익은 토마토여야 하고, 방문한 적 없어야 함
return in_range(f, x, y) and storage[f][x][y] == 0 and not visited[f][x][y]
# bfs()
def bfs():
while q:
f, x, y = q.popleft()
# dfs, dxs, dys
dfs, dxs, dys = [0, 0, 0, 0, -1, 1], [-1, 1, 0, 0, 0, 0], [0, 0, -1, 1, 0, 0]
for df, dx, dy in zip(dfs, dxs, dys):
# 조사 위치
nf, nx, ny = f + df, x + dx, y + dy
# 조사 위치가 익을 수 있는 위치면
if check(nf, nx, ny):
# 방문 표시 해 주고,
visited[nf][nx][ny] = 1
# step 배열 올려주고
step[nf][nx][ny] = step[f][x][y] + 1
# 큐에 넣어주기
q.append((nf, nx, ny))
# blocked()
def blocked():
# storage와 visited를 동시에 돌면서
for f in range(h):
for i in range(n):
for j in range(m):
# storage가 0인데(익지 않은 토마토가 있는데),
# visited가 0인 토마토가 있으면,
if storage[f][i][j] == 0 and not visited[f][i][j]:
# 막힌거임
return True
# 다 돌았는데 그런 토마토가 없으면,
# 안막힌거임
return False
# all_done()
def all_done():
# storage 돌면서
for f in range(h):
for i in range(n):
for j in range(m):
# 안익은 토마토가 있으면
if storage[f][i][j] == 0:
# 실패
return False
# 없으면 성공
return True
# 설계
# 큐 사용 준비
from collections import deque
q = deque()
# 모든 토마토가 익어있는 상태인지 확인
if all_done():
print(0)
# 아니라면,
else:
# visited
visited = [[[0 for _ in range(m)] for _ in range(n)] for _ in range(h)]
# step
step = [[[0 for _ in range(m)] for _ in range(n)] for _ in range(h)]
# storage를 돌면서
for f in range(h):
for i in range(n):
for j in range(m):
# 익은 토마토를 만나면,
if storage[f][i][j] == 1:
# 큐에 좌표를 넣어주고
q.append((f, i, j))
# 방문 처리 해줌
visited[f][i][j] = 1
# 모든 좌표를 넣어주었으면,
# bfs 돌려줌
bfs()
# 만약 bfs 돌린 후에 익지 못한 곳이 있다면,
if blocked():
print(-1)
# 다 익었다면,
else:
# 최댓값 설정
import sys
max_step = -sys.maxsize
# step 돌면서
for f in range(h):
for i in range(n):
for j in range(m):
# 값이 현재 최댓값보다 크다면
if step[f][i][j] > max_step:
# 최댓값 갱신
max_step = step[f][i][j]
# 출력
print(max_step)