[코딩 테스트 - Java] 백준7569 - 토마토

김수빈·2022년 11월 6일
0

코딩테스트

목록 보기
13/16

토마토 7569

INPUT

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N
쌓아올려지는 상자의 수를 나타내는 H
둘째 줄부터는 가장 밑의 상자부터 가장 위의 상자까지에 저장된 토마토들의 정보
정수 1 : 익은 토마토
정수 0 : 익지 않은 토마토
정수 -1: 토마토가 들어있지 않은 칸

OUTPUT

토마토가 모두 익을 때까지 최소 며칠이 걸리는지 출력

LOGIC

백준 7576번 토마토가 2차원 상자라면, 이 문제는 3차원 상자이다. 따라서 위/아래에 대한 조건 설정도 필요하다.

7576번을 풀때 날짜별로 익은 토마토가 전염시킬 수 있는 토마토를 모두 큐에 추가하여서 푸는 것처럼, 이 문제는 위아래도 추가하여 풀면 되기 때문에 크게 어렵지 않았다.

처음 인풋을 기준으로 익은 토마토의 위치를 큐에 추가한다. 이 값을 시작으로 주변을 익게 만들 수 있는 위치를 찾을 것이다.

안익은 토마토의 갯수도 세주어야 한다. 모든 익은 토마토들이 주변을 익게 만든 후에 아직 안익은 토마토가 남아 있다면 -1을 리턴해야 하기 때문이다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;

public class baek7569 {
	// 토마토가 익게 만들 수 있는 6가지 방향
    static int[] dz = { 0, 0, 0, 0, -1, 1 };
    static int[] dy = { 0, 0, -1, 1, 0, 0 };
    static int[] dx = { -1, 1, 0, 0, 0, 0 };
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] data = br.readLine().split(" ");
        int m = Integer.parseInt(data[0]);
        int n = Integer.parseInt(data[1]);
        int h = Integer.parseInt(data[2]);
        int[][][] boxes = new int[h][n][m];

        int count=0;

        Queue<int[]> queue = new LinkedList<>();

        for(int i=0;i<h;i++){
            for(int j=0;j<n;j++){
                String[] d = br.readLine().split(" ");
                for(int k=0;k<m;k++){
                    int tomato = Integer.parseInt(d[k]);

                    if(tomato==0){ // 안익은 토마토 갯수 새기
                        count++;
                    }
                    else if(tomato==1){ // 익은 토마토의 위치 큐에 추가
                        queue.add(new int[]{i,j,k});
                    }

                    boxes[i][j][k]= tomato;
                }
            }
        }

        if(count==0){
            System.out.println(0);
            return;
        }

        // queue 생성 후, 초기 익은 토마토의 위치들을 넣음
        // 이후 큐에 있는 값들을 빼가면서 영향을 주게 바꾸고, 새로 익은 토마토 위치를 큐에 추가
        int answer=0;

        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                int[] location = queue.poll();
                int z = location[0];
                int y = location[1];
                int x = location[2];
                for (int j = 0; j < 6; j++) {
                    int nz = z + dz[j];
                    int ny = y + dy[j];
                    int nx = x + dx[j];
					
                    // 상자 칸을 벗어나는 경우
                    if (nz < 0 || ny < 0 || nx < 0 || nz >= h || ny >= n || nx >= m)
                        continue;
                    // 익지 않은 토마토가 들어있지 않은 경우
                    else if (boxes[nz][ny][nx] != 0)
                        continue;
					
                    // 안익은 토마토의 갯수가 하나 줄어듬
                    count--;
                    // 해당 위치를 익은 토마토로 변경
                    boxes[nz][ny][nx] = 1;
                    // 새로 큐에 추가 (얘가 새로 주변 토마토를 익게 만들 것)
                    queue.add(new int[]{nz, ny, nx});
                }
            }
            answer++;

        }
        // 모두 익게 만들 수 없는 경우
        if(count>0){
            System.out.println(-1);
            return;
        }
        System.out.println(answer-1);
    }
	
    // 3차원 배열 보기 쉽게 출력해주는 메소드
    public static void printArray(int[][][] array){
        for(int[][] data : array){
            for(int[] dat : data){
                for(Integer da : dat){
                    System.out.print(da+" ");
                }
                System.out.println();
            }
            System.out.println();
        }
    }
}

회고

배열이 3차원 부터는 좀 어렵다.. 인덱스가 많이 헷갈린다. 그걸 제외하면 크게 어려운 부분은 없다.

0개의 댓글