전형적인 BFS
문제, 단 시작해야하는 지점이 여러곳이며, 3차원 배열이라는 점을 명심하고 푼다면 쉽게 풀 수 있을 것이다.
일단 시작해야하는 부분들을 먼저 Queue
에 넣고 나서 돌리기 시작하는 방식으로 진행했고, 토마토가 익은 경우에는 기존의 값에서1씩 확대해서 진행하는 식으로 했다. 한번의 탐색이 끝난 경우에도 0 이 존재한다면, 익지 않은 토마토가 있다고 판단하였고, 아닌 경우에는 해당 삼차원 배열안에 가장 큰 값이 바로 토마토 모두 익은 날짜의 값이 된다.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int[][][] map;
static boolean[][][] visited;
static Queue<int[]> q;
static final int[] DI = new int[]{0, 0, 0, 0, -1, 1};
static final int[] DJ = new int[]{0, 0, -1, 1, 0, 0};
static final int[] DK = new int[]{-1, 1, 0, 0, 0, 0};
static int H, M, N;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
H = sc.nextInt();
map = new int[H][M][N];
for (int i = 0; i < H; i++) {
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
map[i][j][k] = sc.nextInt();
}
}
}
visited = new boolean[H][M][N];
q = new LinkedList<>();
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
for (int k = 0; k < map[0][0].length; k++) {
if (map[i][j][k] == 1) {
visited[i][j][k] = true;
q.add(new int[]{i, j, k});
}
}
}
}
BFS();
System.out.println(check());
}
public static void BFS() {
while (!q.isEmpty()) {
int[] curr = q.poll();
int currI = curr[0];
int currJ = curr[1];
int currK = curr[2];
for (int d = 0; d < 6; d++) {
int ni = currI + DI[d];
int nj = currJ + DJ[d];
int nk = currK + DK[d];
if (ni < 0 || nj < 0 || nk < 0 || ni >= H || nj >= M || nk >= N) continue;
if (visited[ni][nj][nk]) continue;
if (map[ni][nj][nk] != 0) continue;
visited[ni][nj][nk] = true;
map[ni][nj][nk] = map[currI][currJ][currK] + 1;
q.add(new int[]{ni, nj, nk});
}
}
}
public static int check() {
int day = 1;
for (int i = 0; i < H; i++) {
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
if (map[i][j][k] == 0) {
return -1;
} else {
day = Math.max(day, map[i][j][k]);
}
}
}
}
return day-1;
}
}