백준 - 토마토

greenTea·2023년 10월 21일
0
post-thumbnail

코드

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;
    }
}

풀이

  1. 값을 먼저 입력받습니다. 이 때 x,y,z축을 이용해야 하기에 3차원 배열을 선언해주었습니다. nx,ny,nz는 각각 다음으로 이동하기 위한 값들을 표현하기 위해 선언하였습니다.
    입력을 받을 때 값이 1인 경우에는 queue에 넣어줍니다.(시작 값)

  2. 전형적인 bfs입니다. 큐가 완전히 비어있을때까지 bfs를 돌립니다. 이때 checkRange를 통해서 다음 값으로 이동할 수 있는지 체크해주었으며 또한 tomato가 0인 경우에만 해당 if문 로직을 사용할 수 있게 하였습니다.(tomato가 0이라는 뜻은 아직 가본적 없는 곳이라는 의미이기 때문입니다. -1은 자동으로 걸려집니다)

  3. if문이 true인 경우 다음 값 = 현재 값 +1을 해주고 queue에 넣어줍니다. 이를 통해 해당 값이 이미 지난 값이라는 표시와 함께 최소 날짜를 표시 하게 됩니다.

  4. 위 while문이 끝난 경우 전체적으로 값을 체크해줍니다. 이 때 0이 있다면 해당 상자는 익을 수 없는 토마토이므로 -1을 반환하고 그것이 아니라면 배열중 최고 값을 찾아서 반환해줍니다. 이 때 최고 값에서 -1을 해주어야 제대로 된 날짜 계산이 된다는 것에 주의해야합니다.

출처 : 백준 - 토마토

profile
greenTea입니다.

0개의 댓글