https://www.acmicpc.net/problem/7576
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
/**
* BOJ7576 - 토마토
* Memory: 121,948KB
* Time: 564ms
*/
class Tomato {
int x;
int y;
int time;
public Tomato(int x, int y, int time) {
this.x = x;
this.y = y;
this.time = time;
}
}
public class Main {
static int N, M; // 가로, 세로 길이
static int maxTime; // 토마토가 전부 익는 데에 걸리는 최대 일수
static int[][] grid; // 토마토 정보를 담은 이차원배열
static Queue<Tomato> tomatos; // 익은 토마토를 담는 배열
static int[] dx = { 0, 0, -1, 1 };
static int[] dy = { -1, 1, 0, 0 };
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// 입력받기
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
maxTime = Integer.MIN_VALUE;
grid = new int[N][M];
tomatos = new LinkedList<>();
// grid에 토마토 정보 담기
for (int i = 0; i < N; i++) {
st = new StringTokenizer(in.readLine(), " ");
for (int j = 0; j < M; j++) {
int time = Integer.parseInt(st.nextToken());
grid[i][j] = time;
// 익은 토마토인 경우 토마토 배열에 추가하기
if (time == 1)
tomatos.add(new Tomato(i, j, time));
}
}
// 하나씩 탐색
bfs();
// 덜 익은 토마토가 있는지 체크하기
boolean isUnripeTomato = false;
loop: for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (grid[i][j] == 0) { // 덜 익은 토마토가 있는 경우
isUnripeTomato = true;
break loop; // 이중 for문을 빠져나오기
}
}
}
// tomato가 있는 위치부터 1로 계산되기 때문에 하나 감소 시켜준다.
System.out.println(isUnripeTomato ? -1 : maxTime - 1);
}
private static void bfs() {
// 익은 토마토가 없어질 때까지 반복
while (!tomatos.isEmpty()) {
Tomato tomato = tomatos.poll();
maxTime = Math.max(maxTime, tomato.time);
for (int i = 0; i < 4; i++) {
int nx = tomato.x + dx[i];
int ny = tomato.y + dy[i];
// 1. 범위를 벗어나지 않고, 2. 익지 않은 토마토가 있으면
if (isValid(nx, ny) && grid[nx][ny] == 0) {
grid[nx][ny] = 1; // 익은 표시 해주고
tomatos.add(new Tomato(nx, ny, tomato.time + 1));
}
}
}
}
private static boolean isValid(int x, int y) {
return 0 <= x && x < N && 0 <= y && y < M;
}
}