0%

BOJ 7576

Input

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다.

둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마토가 들어있지 않은 칸을 나타낸다.

토마토가 하나 이상 있는 경우만 입력으로 주어진다.

1
2
3
4
5
from collections import deque
import sys

M, N = map(int, sys.stdin.readline().split())
tomato = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]

BFS

트리가 1단계씩 깊어질 때마다 기존의 조건을 동일하게 다시 체크해야 함 == BFS

사전 준비

  • 인접한 영역(가로,세로 => dir 로 방향 배열 만들어놓기)

    1
    dir = [[-1,0],[1,0],[0,-1],[0,1]]
  • queue 초기화 시 1 인 위치를 넣어놓는 배열

    1
    2
    3
    4
    5
    6
    ripen = deque()

    for i in range(N):
    for j in range(M):
    if tomato[i][j] == 1:
    ripen.append([i, j])
  • 이미 모두 1 인 경우를 체크할 isAlready boolean

    1
    isAlready = True

  • 체크하고 있는 칸이 범위 내이며 0 일 경우 의 값을 +1 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def bfs():
global isAlready

while ripen:
dx, dy = ripen.popleft()

for d in dir:
x = dx + d[0]
y = dy + d[1]

if 0 <= x < N and 0 <= y < M and tomato[x][y] == 0:
isAlready = False
tomato[x][y] = tomato[dx][dy] + 1
ripen.append([x, y])
  • 이미 모두 1 인 경우 isAlready boolean 값을 이용해 조건에 맞게 답을 출력한다.
  • 배열 전체가 True 가 아닌 경우를 체크해야 하므로 all 을 이용한다.
  • 이 외, bfs 의 결과 출력을 위해 배열 전체에서 max 값을 추출한다.
1
2
3
4
if not all(map(all,tomato)):
sys.stdout.write(str(-1))
elif isAlready: sys.stdout.write(str(0))
else: sys.stdout.write(str(max(map(max, tomato))-1))

위 모두에서 유용하게 쓰인 python 문법: 2차원 배열에서 최종값 하나 출력을 위해…

1
2
max(map(max, tomato))
all(map(all,tomato))

Output

여러분은 토마토가 모두 익을 때까지의 최소 날짜를 출력해야 한다. 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, 토마토가 모두 익지는 못하는 상황이면 -1을 출력해야 한다.

1
2
3
4
5
bfs()
if not all(map(all,tomato)):
sys.stdout.write(str(-1))
elif isAlready: sys.stdout.write(str(0))
else: sys.stdout.write(str(max(map(max, tomato))-1))