Algorithm/BFS & DFS

[๋ฐฑ์ค€, Java] 2573๋ฒˆ : ๋น™์‚ฐ

Zayson 2022. 5. 2. 17:57

๐Ÿ”— ๋ฌธ์ œ ๋งํฌ

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

๐Ÿ˜ฎ ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋น™์‚ฐ์„ ๋…น์—ฌ์•ผ ํ•˜๋Š”์ง€ ํŒ๋‹จ์„ ํ•˜๋Š” ๋ฐฐ์—ด๊ณผ ์‹ค์ œ๋กœ ์ธ์ ‘ํ•œ ๋ฐ”๋‹ค๋ฅผ ์ฒดํฌํ•œ ํ›„ ๋…น์€ ํ›„์˜ ๋น™์‚ฐ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด ๋‘๊ฐœ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๊ฒฐํ–ˆ๋‹ค.

๋น™์‚ฐ ์ƒํƒœ๋ฅผ ๋…น์ด๋Š” ๋ฐฐ์—ด์€ ํ˜„์žฌ ํ•ด์˜ ๋น™์‚ฐ ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•œ ๋ฐฐ์—ด์ด๋‹ค.

  1. ๊ธฐ์กด ๋น™์‚ฐ ๋ฐฐ์—ด์„ ๋…น์€ ํ›„ ๋น™์‚ฐ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์‚ฌํ•œ๋‹ค.
  2. ๊ธฐ์กด ๋น™์‚ฐ ๋ฐฐ์—ด์„ ์ด์šฉํ•ด์„œ ๋น™์‚ฐ์ด ๋‚จ์•„์žˆ๊ณ , ์ƒํ•˜์ขŒ์šฐ ์ธ์ ‘ํ•œ ๋ถ€๋ถ„์— ๋ฐ”๋‹ค๊ฐ€ ์žˆ๋Š”์ง€ ํŒ๋‹จํ•œ๋‹ค.
    • ์ด ๋•Œ, ๋‹จ ํ•˜๋‚˜๋กœ ๋น™์‚ฐ์ด ๋‚จ์•„์žˆ์ง€ ์•Š์•˜๋‹ค๋ฉด, ๋น™์‚ฐ์ด ๋‹ค ๋…น์„๋•Œ ๊นŒ์ง€ ๋‘ ๋ฉ์–ด๋ฆฌ ์ด์ƒ์œผ๋กœ ๋น™์‚ฐ์ด ๋‚˜๋ˆ ์ง€์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— 0์„ ๋ฆฌํ„ดํ•˜๊ณ  ์ข…๋ฃŒํ•œ๋‹ค.
  3. ์ƒํ•˜์ขŒ์šฐ ์ธ์ ‘ํ•œ ๋ฐ”๋‹ค์˜ ๊ฐœ์ˆ˜ ๋งŒํผ ๋น™์‚ฐ์˜ ํฌ๊ธฐ๋ฅผ ๋…น์—ฌ์ค€๋‹ค.
  4. ํ˜„์žฌ ํ•ด์˜ ๋…น์ผ ์ˆ˜ ์žˆ๋Š” ๋น™์‚ฐ์„ ๋ชจ๋‘ ์ฒดํฌํ–ˆ๋‹ค๋ฉด, ํ˜„์žฌ ํ•ด๋ฅผ ์ฆ๊ฐ€ ์‹œํ‚จ๋‹ค.
  5. ๋น™์‚ฐ์ด ๋‘๋ฉ์–ด๋ฆฌ๋กœ ๋‚˜๋‰˜์–ด ์กŒ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
    • BFS๋ฅผ ์ด์šฉํ•ด ํ˜„์žฌ ๋น™์‚ฐ์ด ๋‚˜๋‰˜์–ด์กŒ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
    • ํ˜„์žฌ ์ƒํƒœ์˜ ๋น™์‚ฐ์— ๋Œ€ํ•ด์„œ BFS๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ๋ฒˆ ์ด์–ด์ ธ์ž‡๋Š” ๋น™์‚ฐ ๋ฉ์–ด๋ฆฌ๋ฅผ ๊ตฌํ–ˆ๋‹ค๋ฉด, ์ดํ›„์˜ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋น™์‚ฐ์ด ๋‚จ์•„์žˆ๋‹ค๋ฉด BFS ๋กœ์ง์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋‘ ๋ฉ์–ด๋ฆฌ ์ด์ƒ์œผ๋กœ ๋‚˜๋‰˜์–ด์กŒ๋‹ค๊ณ  ํŒ๋‹จ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  6. ๋‘ ๋ฉ์–ด๋ฆฌ ์ด์ƒ์œผ๋กœ ๋น™์‚ฐ์ด ๋…น์•„์ง€์ง€ ์•Š์•˜๋‹ค๋ฉด, ๋‹ค์Œ ํ•ด์˜ ๊ธฐ์กด ๋น™์‚ฐ ๋ฐฐ์—ด์ด ํ˜„์žฌ ๋…น์ธ ์ƒํƒœ์˜ ๋ฐฐ์—ด ๊ฐ’์œผ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์žฌ๋ณต์‚ฌ๋ฅผ ํ•ด์ค€๋‹ค.

์ด๋Ÿฌํ•œ ๋กœ์ง์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿšฉ Java ์ฝ”๋“œ

package com.algorithm.Baekjoon;

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

public class Main_2573_๋น™์‚ฐ {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        int[][] iceberg = new int[N][M];
        for(int row = 0; row < N; row++) {
            st = new StringTokenizer(br.readLine());
            for(int col = 0; col < M; col++) {
                iceberg[row][col] = Integer.parseInt(st.nextToken());
            }
        }

        int rst = getMinYear(N, M, iceberg);
        System.out.println(rst);

        br.close();
    }

    private static final int[] DX = {1, -1, 0, 0};
    private static final int[] DY = {0, 0, 1, -1};
    private static int getMinYear(int n, int m, int[][] iceberg) {
        /**
         * 1. ๊ธฐ์กด ๋น™์‚ฐ ๋ฐฐ์—ด์„ ์ƒˆ๋กœ์šด ๋น™์‚ฐ ๋ฐฐ์—ด๋กœ ํ•˜๋‚˜ ๋ณต์‚ฌํ•˜๊ธฐ
         * 2. ๊ธฐ์กด ๋น™์‚ฐ ๋ฐฐ์—ด์„ ์ด์šฉํ•ด ๋‚จ์€ ๋‚จ์•„์žˆ๋Š” ๋น™์‚ฐ์˜ ์ƒํ•˜์ขŒ์šฐ์— ๋ฐ”๋‹ค๊ฐ€ ์ธ์ ‘ํ•ด์žˆ๋Š”์ง€ ์ฒดํฌ
         * 3. ์ƒˆ๋กœ ๋ณต์‚ฌํ•œ ๋น™์‚ฐ ๋ฐฐ์—ด์— ์ธ์ ‘ํ•œ ๋ฐ”๋‹ค ๊ฐœ์ˆ˜ ๋งŒํผ ๋…น์ด๊ธฐ
         * 3-1. ํ˜„์žฌ ํ•ด์— ํ•œ๋ฒˆ๋„ ๋น™์‚ฐ์„ ๋…น์ด์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋‹ค ๋…น์•˜์ง€๋งŒ ๋‘ ๋ฉ์–ด๋ฆฌ๋กœ ๋‚˜๋ˆ ์ง€์ง€ ์•Š์€ ๊ฒฝ์šฐ๋ฏ€๋กœ return 0;
         * 4. ํ˜„์žฌ ํ•ด์— ๋…น์ผ ์ˆ˜ ์žˆ๋Š” ๋น™์‚ฐ์„ ๋…น์˜€์œผ๋ฏ€๋กœ, ํ˜„์žฌ ํ•ด๋ฅผ 1 ์ฆ๊ฐ€
         * 5. ๋น™์‚ฐ์ด ๋‘ ๋ฉ์–ด๋ฆฌ ์ด์ƒ์œผ๋กœ ๋‚˜๋‰˜์–ด์กŒ๋Š”์ง€ ํŒ๋‹จํ•˜๊ธฐ
         * 6. ๋‚˜๋‰˜์–ด ์ง€์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋‹ค์Œ ํ•ด์˜ ๊ธฐ์กด ๋ฐฐ์—ด๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์‚ฌ
         */
        int year = 0;
        while(true) {

            // 1. ๊ธฐ์กด ๋ฐฐ์—ด ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ๋ณต์‚ฌ
            int[][] copyIceberg = copyArray(n,m, iceberg);

            boolean remainIceberg = false;          // ํ˜„์žฌ ํ•ด์— ๋‚จ์€ ๋น™์‚ฐ์ด ์žˆ๋Š”์ง€ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด
            for(int row =0; row < n; row++) {
                for(int col = 0; col < m; col++) {
                    // 2. ๋‚จ์•„์žˆ๋Š” ๋น™์‚ฐ์ด ์žˆ๊ณ  ์ƒํ•˜์ขŒ์šฐ ๋ฐ”๋‹ค ํŒ๋‹จ
                    if(iceberg[row][col] != 0) {
                        int meltCount = 0;
                        for(int direction = 0; direction < 4; direction++) {
                            int checkRow = DX[direction] + row;
                            int checkCol = DY[direction] + col;
                            if(checkBound(checkRow, checkCol, n,m) && iceberg[checkRow][checkCol] == 0) {
                                meltCount++;        // ์ƒํ•˜์ขŒ์šฐ์˜ ๋ฐ”๋‹ค ๊ฐœ์ˆ˜ ๊ตฌํ•˜๊ธฐ
                            }
                        }
                        // 3. ์ƒˆ๋กœ ๋ณต์‚ฌํ•œ ๋น™์‚ฐ ๋ฐฐ์—ด์— ์ธ์ ‘ํ•œ ๋ฐ”๋‹ค ๊ฐœ์ˆ˜ ๋งŒํผ ๋…น์ด๊ธฐ
                        copyIceberg[row][col] = Math.max(copyIceberg[row][col] - meltCount, 0);     // 0 ๋ณด๋‹ค ํฌ๋ฉด ๋น™์‚ฐ ๋…น์ธ ํฌ๊ธฐ ์•„๋‹ˆ๋ฉด ๋‹ค ๋…น์€ ๊ฒฝ์šฐ
                        remainIceberg = true;       // ํ•œ๋ฒˆ์ด๋ผ๋„ ๋น™์‚ฐ์„ ๋…น์˜€์œผ๋ฉด ๋‚จ์€ ๋น™์‚ฐ์ด ์žˆ์—ˆ๋‹ค๋Š” ๋œป
                    }
                }  
            }

            // 3-1. ๋น™์‚ฐ์ด ๋‹ค ๋…น์•˜์ง€๋งŒ ๋‘ ๋ฉ์–ด๋ฆฌ๋กœ ์•ˆ๋‚˜๋ˆ ์ง„ ๊ฒฝ์šฐ
            if(!remainIceberg) {
                year = 0;
                break;
            }

            // 4. ๋น™์‚ฐ ๋…น์ด๊ณ  ์ผ๋…„ ๋ณด๋‚ด๊ธฐ
            year++;
            
            // 5. ๋น™์‚ฐ์ด ๋‘๊ฐˆ๋ž˜ ์ด์ƒ์œผ๋กœ ๋‚˜๋ˆ ์กŒ๋Š”์ง€ ํŒ๋‹จ
            if(isDivide(copyIceberg, n,m)) break;
            
            // 6. ๋‹ค ๋…น์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ธฐ์กด ๋ฐฐ์—ด์„ ๋‚จ์€ ๋น™์‚ฐ ๋ฐฐ์—ด๋กœ ๋ณต์‚ฌ
            iceberg = copyArray(n, m, copyIceberg);
        }
        return year;
    }

    private static boolean isDivide(int[][] copyIceberg, int n, int m) {
        boolean[][] visited = new boolean[n][m];
        boolean isDivide = false;

        for(int row =0; row < n; row++) {
            for(int col = 0; col < m; col++) {
                if(!visited[row][col] && copyIceberg[row][col] != 0) {
                    if(isDivide) return true;       // ์ด์–ด์ง„ ๋น™์‚ฐ ํ•œ๋ฒˆ ํƒ์ƒ‰ํ•œ ๊ฒฝ์šฐ ๋‹ค์Œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋น™์‚ฐ์€ ๋‚˜๋ˆ ์ง„ ๊ฒฝ์šฐ์ด๊ธฐ ๋•Œ๋ฌธ์— true

                    bfs(copyIceberg, row, col, n, m, visited);
                    isDivide = true;        // ํ•˜๋‚˜์˜ ์ด์–ด์ง„ ๋น™์‚ฐ์„ ๊ตฌํ•จ
                }
            }
        }
        return false;
    }

    private static void bfs(int[][] copyIceberg, int row, int col, int n, int m, boolean[][] visited) {
        // ์ด์–ด์ง„ ๋น™์‚ฐ ์ฒดํฌํ•˜๊ธฐ
        Queue<Point> queue = new LinkedList<>();
        queue.add(new Point(row, col));

        while(!queue.isEmpty()) {
            Point curPoint = queue.poll();
            int curRow = curPoint.getRow();
            int curCol = curPoint.getCol();

            if(visited[curRow][curCol]) continue;
            visited[curRow][curCol] = true;
            for(int direction = 0; direction < 4; direction++) {
                int nextRow = curRow + DX[direction];
                int nextCol = curCol + DY[direction];
                if(checkBound(nextRow,nextCol, n,m) && !visited[nextRow][nextCol] && copyIceberg[nextRow][nextCol] != 0) {
                    queue.add(new Point(nextRow, nextCol));
                }
            }
        }
    }

    private static boolean checkBound(int checkRow, int checkCol, int n, int m) {
        return checkRow >= 0 && checkRow < n && checkCol >= 0 && checkCol < m;
    }

    private static int[][] copyArray(int n, int m, int[][] iceberg) {
        int[][] copyIceberg = new int[n][m];
        for(int row = 0; row < n; row++) {
            for(int col = 0; col < m; col++) {
                copyIceberg[row][col] = iceberg[row][col];
            }
        }
        return copyIceberg;
    }

    static class Point {
        private int row;
        private int col;

        public Point(int row, int col) {
            this.row = row;
            this.col = col;
        }

        public int getRow() {
            return row;
        }

        public int getCol() {
            return col;
        }
    }
}
๋ฐ˜์‘ํ˜•