🤢 기존 그래프 문제에 비해 특이점은 2차원 배열이 아니라 3차원 배열이라는 것을 인지해야 한다는 점이다.
토마토들이 병렬적으로 각각 번지기 때문에 이를 고려하여 루프를 짜야한다
앞뒤상하좌우 라는 방향벡터를 설정해야한다
그외에는 기존 BFS 그래프 탐색
과 동일하다고 보인다.
// 1 인 지점부터 시작하여 상하좌우앞뒤로 퍼지게 된다, 관건은 상하에 대한 고려를 해주어야 한다는 점, 방향벡터에 대한 설정이 필요
// 방향 벡터에 대한 설정, dz 가 추가적으로 들어감, 기본적인 순서는 상하좌우위아래가 됨
static int[] dx = {-1,1,0,0,0,0};
static int[] dy = {0,0,-1,1,0,0};
static int[] dz = {0,0,0,0,-1,1};
static int tomatoCnt; // 익혀야할 토마토의 개수
static int[][][] graph;
static int m,n,h;
static Queue<Point> queue;
익혀야할 토마토 개수
가 증가한다고 하였을 때, BFS를 수행하지 않아도 익혀야할 토마토 개수가 0 인경우에는 바로 반환할 수 있도록 따로 토마토 개수를 저장한다상,하
가 있는데 상하좌우위아래의 방향 벡터를 미리 지정한다static
으로 설정해준다// 좌표값을 저장할 객체 생성
static class Point{
private int z;
private int x;
private int y;
public int getZ() {
return z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Point(int z, int x, int y) {
this.z = z;
this.x = x;
this.y = y;
}
}
동시에 일어난다
. 이점을 유의하여 함수를 설계한다 static int bfs(){
int ret = 0; // 익힌 일수
// 큐가 비지 않을때 동안 계속 순회
while(queue.size()>0){
// 익은 토마토들은 동시에 익힌다고 가정, for loop 를 한번 더 거친다
int initCase = queue.size();
for (int j = 0; j < initCase; j++) {
Point now = queue.poll(); // 현재 토마토를 꺼내온다
int currZ = now.getZ();
int currX = now.getX();
int currY = now.getY();
// 상하좌우로 돌면서 이동 후 위치를 계산
for (int i = 0; i < 6; i++) {
int nz = currZ+dz[i];
int nx = currX+dx[i];
int ny = currY+dy[i];
// 맵의 범위를 벗어나면 다음 방향으로 넘김
if (nz < 0 || nx < 0 || ny < 0 || nz >= h || nx >= n || ny >= m) continue;
if (graph[nz][nx][ny] == 0){
// 큐에 담아주고 방문처리
queue.add(new Point(nz,nx,ny));
// 토마토의 개수 -1
tomatoCnt--;
// 토마토의 방문처리
graph[nz][nx][ny] = 1;
}
}
}
ret++;
}
if(tomatoCnt==0) return ret-1;
else return -1;// 모두 익히지 못한 경우, -1 반환
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] graphSize = bf.readLine().split(" ");
m = Integer.parseInt(graphSize[0]); // 가로칸의 수 y
n = Integer.parseInt(graphSize[1]); // 세로 칸의 수 x
h = Integer.parseInt(graphSize[2]); // 높이 h
queue = new LinkedList<>();
graph = new int[h][n][m];
tomatoCnt = 0;
// 배열값 세팅
for (int i = 0; i < h; i++) {
for (int j = 0; j < n; j++) {
StringTokenizer st = new StringTokenizer(bf.readLine());
for (int k = 0; k < m; k++) {
int t = Integer.parseInt(st.nextToken());
if (t==0) {
tomatoCnt ++;
}
else if(t==1) queue.add(new Point(i,j,k)); // 1 인 경우 토마토들을 저장
graph[i][j][k] = t;
}
}
}
bf.close();
if(tomatoCnt == 0) System.out.println(0); // 익혀야할 토마토가 없는경우 바로 0 반환
else System.out.println(bfs());
}