μ•Œκ³ λ¦¬μ¦˜

[Java] BOJ 7576 ν† λ§ˆν† 

🍊귀🍊 2024. 9. 2. 15:53

문제 

문제 링크 https://www.acmicpc.net/problem/7576

  • 철수의 ν† λ§ˆν†  농μž₯μ—μ„œλŠ” ν† λ§ˆν† λ₯Ό λ³΄κ΄€ν•˜λŠ” 큰 μ°½κ³ λ₯Ό κ°€μ§€κ³  μžˆλ‹€. ν† λ§ˆν† λŠ” μ•„λž˜μ˜ κ·Έλ¦Όκ³Ό 같이 격자 λͺ¨μ–‘ μƒμžμ˜ 칸에 ν•˜λ‚˜μ”© λ„£μ–΄μ„œ 창고에 λ³΄κ΄€ν•œλ‹€.
  • 창고에 λ³΄κ΄€λ˜λŠ” ν† λ§ˆν† λ“€ μ€‘μ—λŠ” 잘 읡은 것도 μžˆμ§€λ§Œ, 아직 읡지 μ•Šμ€ ν† λ§ˆν† λ“€λ„ μžˆμ„ 수 μžˆλ‹€.
  • 보관 ν›„ ν•˜λ£¨κ°€ μ§€λ‚˜λ©΄, 읡은 ν† λ§ˆν† λ“€μ˜ μΈμ ‘ν•œ 곳에 μžˆλŠ” 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ€ 읡은 ν† λ§ˆν† μ˜ 영ν–₯을 λ°›μ•„ 읡게 λœλ‹€.
  • ν•˜λ‚˜μ˜ ν† λ§ˆν† μ˜ μΈμ ‘ν•œ 곳은 μ™Όμͺ½, 였λ₯Έμͺ½, μ•ž, λ’€ λ„€ λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ₯Ό μ˜λ―Έν•œλ‹€. λŒ€κ°μ„  λ°©ν–₯에 μžˆλŠ” ν† λ§ˆν† λ“€μ—κ²ŒλŠ” 영ν–₯을 μ£Όμ§€ λͺ»ν•˜λ©°, ν† λ§ˆν† κ°€ 혼자 μ €μ ˆλ‘œ μ΅λŠ” κ²½μš°λŠ” μ—†λ‹€κ³  κ°€μ •ν•œλ‹€.
  • μ² μˆ˜λŠ” 창고에 λ³΄κ΄€λœ ν† λ§ˆν† λ“€μ΄ 며칠이 μ§€λ‚˜λ©΄ λ‹€ 읡게 λ˜λŠ”μ§€, κ·Έ μ΅œμ†Œ 일수λ₯Ό μ•Œκ³  μ‹Άμ–΄ ν•œλ‹€.
  • ν† λ§ˆν† λ₯Ό 창고에 λ³΄κ΄€ν•˜λŠ” 격자λͺ¨μ–‘μ˜ μƒμžλ“€μ˜ 크기와 읡은 ν† λ§ˆν† λ“€κ³Ό 읡지 μ•Šμ€ ν† λ§ˆν† λ“€μ˜ 정보가 μ£Όμ–΄μ‘Œμ„ λ•Œ, 며칠이 μ§€λ‚˜λ©΄ ν† λ§ˆν† λ“€μ΄ λͺ¨λ‘ μ΅λŠ”μ§€, κ·Έ μ΅œμ†Œ 일수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜λΌ.
  • 단, μƒμžμ˜ 일뢀 μΉΈμ—λŠ” ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.
  • 첫 μ€„μ—λŠ” μƒμžμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •μˆ˜ M,N이 μ£Όμ–΄μ§„λ‹€.
  • M은 μƒμžμ˜ κ°€λ‘œ 칸의 수, N은 μƒμžμ˜ μ„Έλ‘œ 칸의 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 단, 2 ≤ M,N ≤ 1,000 이닀.
  • λ‘˜μ§Έ μ€„λΆ€ν„°λŠ” ν•˜λ‚˜μ˜ μƒμžμ— μ €μž₯된 ν† λ§ˆν† λ“€μ˜ 정보가 μ£Όμ–΄μ§„λ‹€.
  • 즉, λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” μƒμžμ— λ‹΄κΈ΄ ν† λ§ˆν† μ˜ 정보가 μ£Όμ–΄μ§„λ‹€. ν•˜λ‚˜μ˜ μ€„μ—λŠ” μƒμž κ°€λ‘œμ€„μ— λ“€μ–΄μžˆλŠ” ν† λ§ˆν† μ˜ μƒνƒœκ°€ M개의 μ •μˆ˜λ‘œ μ£Όμ–΄μ§„λ‹€.
  • μ •μˆ˜ 1은 읡은 ν† λ§ˆν† , μ •μˆ˜ 0은 읡지 μ•Šμ€ ν† λ§ˆν† , μ •μˆ˜ -1은 ν† λ§ˆν† κ°€ λ“€μ–΄μžˆμ§€ μ•Šμ€ 칸을 λ‚˜νƒ€λ‚Έλ‹€.
  • ν† λ§ˆν† κ°€ ν•˜λ‚˜ 이상 μžˆλŠ” 경우만 μž…λ ₯으둜 μ£Όμ–΄μ§„λ‹€.
  • μ—¬λŸ¬λΆ„μ€ ν† λ§ˆν† κ°€ λͺ¨λ‘ 읡을 λ•ŒκΉŒμ§€μ˜ μ΅œμ†Œ λ‚ μ§œλ₯Ό 좜λ ₯ν•΄μ•Ό ν•œλ‹€. λ§Œμ•½, μ €μž₯될 λ•ŒλΆ€ν„° λͺ¨λ“  ν† λ§ˆν† κ°€ μ΅μ–΄μžˆλŠ” μƒνƒœμ΄λ©΄ 0을 좜λ ₯ν•΄μ•Ό ν•˜κ³ , ν† λ§ˆν† κ°€ λͺ¨λ‘ μ΅μ§€λŠ” λͺ»ν•˜λŠ” 상황이면 -1을 좜λ ₯ν•΄μ•Ό ν•œλ‹€.

아이디어

  • 3차원 ν† λ§ˆν† λž‘ λΉ„μŠ·ν•˜κ²Œ ν’€μ—ˆλ‹€.
  • BFSλ₯Ό μ¨μ„œ ν’€μ—ˆλŠ”λ° 이 λ¬Έμ œλŠ” x,yμ’Œν‘œλ‘œ μƒν•˜μ’Œμš° νƒμƒ‰λ§Œ ν•˜λ©΄ λΌμ„œ μ’€ 더 κ°„λ‹¨νžˆ ν’€ 수 μžˆμ—ˆλ‹€.
  • μž…λ ₯을 받을 λ•Œλ§ˆλ‹€ 값이 1일 경우, Queue에 Pointλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή μ’Œν‘œλ₯Ό λ„£λŠ”λ‹€.
  • Queue에 μžˆλŠ” μ’Œν‘œκ°’μ˜ 개수만큼  λ°˜λ³΅λ¬Έμ„ λŒμ•„ μƒˆλ‘­κ²Œ 읡은 ν† λ§ˆν† μ˜ μ’Œν‘œλ₯Ό Queue에 λ„£λŠ”λ‹€. (기쑴에 Queue에 있던 개수만큼 반볡문이 λŒκΈ°λ•Œλ¬Έμ— μƒˆλ‘­κ²Œ Queue에 λ“€μ–΄κ°„ μ’Œν‘œκ°’μ€ λ‚ μ§œκ°€ λ„˜μ–΄κ°€κ³  μƒˆλ‘œμš΄ λ°˜λ³΅λ¬Έμ—μ„œ μ‚¬μš©λœλ‹€.)
  • λ°˜λ³΅λ¬Έμ„ 돌며 μƒˆλ‘­κ²Œ μΆ”κ°€λœ ν† λ§ˆν†  μ’Œν‘œκ°€ μžˆλ‹€λ©΄ λ‚ μ§œλ₯Ό + 1μ‹œν‚€κ³  while문을 톡해 μ΅œμ’…μ μœΌλ‘œ Queueκ°€ 빌 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.
  • 좜λ ₯ν•  λ•ŒλŠ”, μž…λ ₯받을 λ•ŒλΆ€ν„° μ΅ν˜€μ•Όλ˜λŠ” ν† λ§ˆν† κ°€ μ—†μ—ˆλ‹€λ©΄ λ°”λ‘œ 0을 좜λ ₯ν•˜κ³  아닐 경우, μ’Œν‘œλ₯Ό 돌며 남은 0이 μžˆλ‹€λ©΄ -1, μ—†λ‹€λ©΄ κ³„μ‚°λœ λ‚ μ§œ 수λ₯Ό 좜λ ₯ν•œλ‹€.

κ²ͺ은 μ‹œν–‰μ°©μ˜€

  • X

μ–΄μ œ λ¬Έμ œμ™€ λΉ„μŠ·ν•΄μ„œ λ‚˜λ¦„ μˆ˜μ›”ν•˜κ²Œ ν’€μ—ˆλ‹€!

μ½”λ“œ

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

public class BOJ7576 {

    static int M;
    static int N;
    static int map[][];
    static boolean visited[][];
    static int dx[] = {-1, 1, 0, 0};
    static int dy[] = {0, 0, -1, 1};
    static int days;
    static Queue<Point> q = new LinkedList<>();

    public static void main(String[] args) 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());

        // μ΅μ–΄μ•Όλ˜λŠ” ν† λ§ˆν† κ°€ μžˆλŠ”μ§€ νŒλ‹¨ν•  λ³€μˆ˜
        boolean isTomato = false;

        // ν† λ§ˆν†  μ €μž₯ν•  λ°°μ—΄
        map = new int[N][M];
        // λ°©λ¬Έ μ—¬λΆ€ μ €μž₯ν•  λ°°μ—΄
        visited = new boolean[N][M];
        // 계산할 λ‚ μ§œ λ³€μˆ˜
        days = 0;

        // ν† λ§ˆν†  μž…λ ₯
        for(int i = 0; i < N; i++){
            StringTokenizer st2 = new StringTokenizer(br.readLine());

            for(int j = 0; j < M; j++){
                int n = Integer.parseInt(st2.nextToken());

                // λ§Œμ•½ μž…λ ₯이 0이라면 μ΅ν˜€μ•Όλ˜λŠ” ν† λ§ˆν† κ°€ μžˆλ‹€λŠ” λœ»μ΄λ―€λ‘œ
                // λ³€μˆ˜λ₯Ό true둜 λ°”κΏ”μ€Œ
                if(n == 0){
                    isTomato = true;
                }

                // μž…λ ₯이 1이면 ν† λ§ˆν† κ°€ μžˆλ‹€λŠ” λœ»μ΄λ―€λ‘œ Queue에
                // ν•΄λ‹Ή μœ„μΉ˜λ₯Ό λ„£μ–΄μ£Όκ³  방문처리
                if(n == 1){
                    q.offer(new Point(i, j));
                    visited[i][j] = true;
                }

                map[i][j] = n;
            }
        }

        if(!isTomato){
            System.out.println(0);
        }
        else{
            // λͺ¨λ‘ 읡힐 수 μžˆλŠ” 상황인지 νŒλ‹¨ν•  λ³€μˆ˜
            boolean TF = true;

            BFS();

            for(int i = 0; i < N; i++){
                for(int j = 0; j < M; j++){
                    // λ§Œμ•½ BFSλ₯Ό λŒλ ΈλŠ”λ° 아직 0이 μžˆλ‹€λ©΄
                    // λͺ¨λ‘ λͺ» μ΅ν˜”μœΌλ―€λ‘œ TFλ₯Ό false둜 λ°”κΎΈκ³  반볡문 μ’…λ£Œ
                    if(map[i][j] == 0){
                        TF = false;
                        break;
                    }
                }
            }

            // λ§Œμ•½ TFκ°€ true이면 λͺ¨λ‘ 읡힐 수 μžˆλ‹€λŠ” λœ»μ΄λ―€λ‘œ λ‚ μ§œ 좜λ ₯
            if(TF){
                System.out.println(days);
            }
            // TFκ°€ false라면 λͺ¨λ‘ 읡힐 수 μ—†λ‹€λŠ” λœ»μ΄λ―€λ‘œ -1 좜λ ₯
            else{
                System.out.println(-1);
            }
        }
    }

    public static void BFS(){
        // Queueκ°€ λΉŒλ•ŒκΉŒμ§€ 반볡
        while(!q.isEmpty()){
            // Queue의 크기
            int size = q.size();
            // μƒˆλ‘œμš΄ ν† λ§ˆν† κ°€ μƒκ²ΌλŠ”μ§€ νŒλ‹¨ν•  λ³€μˆ˜
            boolean change = false;

            // 기쑴의 Queue 크기만큼 반볡
            for(int i = 0; i < size; i++){
                int xx = q.peek().x;
                int yy = q.peek().y;

                q.poll();

                // Queueμ—μ„œ κΊΌλ‚Έ μ’Œν‘œλ₯Ό κΈ°μ€€μœΌλ‘œ
                // μƒν•˜μ’Œμš°λ‘œ 이동
                for(int j = 0; j < 4; j++){
                    int nx = xx + dx[j];
                    int ny = yy + dy[j];

                    // μ΄λ™ν•œ μ’Œν‘œκ°€ λ²”μœ„λ₯Ό μ΄ˆκ³Όν•œλ‹€λ©΄ continue
                    if(nx >= N || nx < 0 || ny >= M || ny < 0){
                        continue;
                    }

                    // λ§Œμ•½ μ΄λ™ν•œ μ’Œν‘œκ°€ 0이고 λ°©λ¬Έν•˜μ§€ μ•Šμ•˜λ‹€λ©΄
                    if((map[nx][ny] == 0) && !visited[nx][ny]){
                        // ν•΄λ‹Ήμ’Œν‘œλ₯Ό 1둜 λ°”κΎΈκ³ 
                        map[nx][ny] = 1;
                        // 방문처리λ₯Ό ν•œ ν›„,
                        visited[nx][ny] = true;
                        // Queue에 λ„£μŒ
                        q.offer(new Point(nx, ny));
                        // 그리고 μƒˆλ‘œμš΄ ν† λ§ˆν† κ°€ μƒκ²ΌμœΌλ―€λ‘œ true둜 λ°”κΏˆ
                        change = true;
                    }
                }
            }

            // 그리고 μƒˆλ‘œμš΄ ν† λ§ˆν† κ°€ μƒκ²ΌμœΌλ©΄ λ‚ μ§œ + 1
            if(change){
                days = days + 1;
            }
        }
    }
}