public class Main {
static int[] nx = new int[]{1, 0, -1, 0, 0, 0};
static int[] ny = new int[]{0, 1, 0, -1, 0, 0};
static int[] nz = new int[]{0, 0, 0, 0, -1, 1};
static int M, N, H;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
M = Integer.parseInt(st.nextToken());
N = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
int[][][] tomato = new int[H][N][M];
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
st = new StringTokenizer(br.readLine());
for (int k = 0; k < M; k++) {
int current = Integer.parseInt(st.nextToken());
tomato[i][j][k] = current;
if (current == 1)
queue.offer(new int[]{i, j, k});
}
}
}
while (!queue.isEmpty()) {
int[] poll = queue.poll();
int h = poll[0]; //z
int y = poll[1]; //y
int x = poll[2]; //x
for (int u = 0; u < 6; u++) {
int hh = h + nz[u];
int xx = x + nx[u];
int yy = y + ny[u];
if (checkRange(hh, xx, yy) && tomato[hh][yy][xx] == 0) {
tomato[hh][yy][xx] = tomato[h][y][x] + 1;
queue.offer(new int[]{hh, yy, xx});
}
}
}
System.out.println(checkArray(tomato));
}
private static boolean checkRange(int h, int x, int y) {
return h >= 0 && x >= 0 && y >= 0 && h < H && y < N && x < M;
}
private static int checkArray(int[][][] arr) {
int ans = 0;
for (int i = 0; i < H; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < M; k++) {
if (arr[i][j][k] == 0)
return -1;
ans = Math.max(arr[i][j][k],ans);
}
}
}
return ans-1;
}
}
- 값을 먼저 입력받습니다. 이 때 x,y,z축을 이용해야 하기에 3차원 배열을 선언해주었습니다. nx,ny,nz는 각각 다음으로 이동하기 위한 값들을 표현하기 위해 선언하였습니다.
입력을 받을 때 값이 1인 경우에는queue
에 넣어줍니다.(시작 값)
- 전형적인
bfs
입니다. 큐가 완전히 비어있을때까지bfs
를 돌립니다. 이때checkRange
를 통해서 다음 값으로 이동할 수 있는지 체크해주었으며 또한 tomato가 0인 경우에만 해당 if문 로직을 사용할 수 있게 하였습니다.(tomato가 0이라는 뜻은 아직 가본적 없는 곳이라는 의미이기 때문입니다. -1은 자동으로 걸려집니다)
- if문이 true인 경우
다음 값 = 현재 값 +1
을 해주고 queue에 넣어줍니다. 이를 통해 해당 값이 이미 지난 값이라는 표시와 함께 최소 날짜를 표시 하게 됩니다.
- 위 while문이 끝난 경우 전체적으로 값을 체크해줍니다. 이 때 0이 있다면 해당 상자는 익을 수 없는 토마토이므로 -1을 반환하고 그것이 아니라면 배열중 최고 값을 찾아서 반환해줍니다. 이 때 최고 값에서 -1을 해주어야 제대로 된 날짜 계산이 된다는 것에 주의해야합니다.
출처 : 백준 - 토마토