알고리즘/그래프 탐색

[BOJ 7569] 토마토 (Java, 그래프 탐색)

leejinwoo1126 2023. 6. 9. 23:16
반응형

 

 


문제 링크 

https://www.acmicpc.net/problem/7569

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net


풀이 

- 3차원 배열의 그래프 탐색 문제 

- 필드 초기화시 가로,세로,높이 변수가 혼란스러워 시간소요함 (그외에는 문제에서 요구하는 바와 같이 그대로 풀이하면 됨)

- multisource bfs로 토마토(1)의 위치를 찾고, 위치값을 0으로 초기화(나머지는 -1)

- 상하좌우위아래로 격자형 그래프 풀 듯이 이동하면서 위치값을 갱신하여 마지막에 최대값 찾으면 됨

- 시간 복잡도 : O(N^3), 최대 인자가 100이기때문에 Integer로 충분히 풀이 가능

 

초등부 문제라서 이 악물고 풀었다 :0
3차원 정의에서 실수가 있어서 그렇지 동일한 격자형 그래프 탐색 문제였다

제출 코드

import java.util.*;
import java.io.*;

public class Main {
    
    static int M, N, H;

    static int[][][] BOX;
    static int[][][] DAYS;

    static int[][] direction = {{0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, -1, 0}};

    static void input() throws Exception {
        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()); // 토마토 박스 번호

        DAYS = new int[N + 1][M + 1][H + 1];
        BOX = new int[N + 1][M + 1][H + 1];

        for(int k = 1; k <= H; k++) {
            for(int i = 1; i <= N; i++) { // 세로
                st = new StringTokenizer(br.readLine());
                for(int j = 1; j <= M; j++) { // 가로
                    BOX[i][j][k] = Integer.parseInt(st.nextToken());
                }
            }
        }
    }

    static void bfs() {
        Queue<Integer> que = new LinkedList<>();

        // 토마토 찾기
        for(int k = 1; k <= H; k++) {
            for(int i = 1; i <= N; i++) { // 세로
                for(int j = 1; j <= M; j++) { // 가로
                    DAYS[i][j][k] = -1;
                    if(BOX[i][j][k] == 1) {
                        que.add(i);
                        que.add(j);
                        que.add(k);
                        DAYS[i][j][k] = 0;
                    }
                }
            }
        }

        while(!que.isEmpty()) {
            int x = que.poll(), y = que.poll(), z = que.poll();

            for(int i = 0; i < 6; i++) {
                int nx = x + direction[i][0];
                int ny = y + direction[i][1];
                int nz = z + direction[i][2];

                if(nx < 1 || ny < 1 || nz < 1 || nx > N || ny > M || nz > H) continue;
                if(BOX[nx][ny][nz] != 0 || DAYS[nx][ny][nz] != -1) continue;

                que.add(nx);
                que.add(ny);
                que.add(nz);

                DAYS[nx][ny][nz] = DAYS[x][y][z] + 1;
            }
        }
    }

    static void pro() {
        bfs();

        int maxDay = 0;
        Loop1 :
        for(int k = 1; k <= H; k++) {
            for(int i = 1; i <= N; i++) { // 세로
                for(int j = 1; j <= M; j++) { // 가로
                   if(BOX[i][j][k] == 0 && DAYS[i][j][k] == -1) {
                       maxDay = -1;
                       break Loop1;
                   }

                   if(BOX[i][j][k] == 0 && maxDay < DAYS[i][j][k]) {
                       maxDay = DAYS[i][j][k];
                   }
                }
            }
        }

        System.out.println(maxDay);
    }

    public static void main(String[] args) throws Exception {
        input();
        pro();
    }
    
}
반응형