๊ธฐ๋ก๋ฐฉ

BOJ_1113 : ์ˆ˜์˜์žฅ ๋งŒ๋“ค๊ธฐ ๋ณธ๋ฌธ

CodingTest/Java

BOJ_1113 : ์ˆ˜์˜์žฅ ๋งŒ๋“ค๊ธฐ

Soom_1n 2024. 8. 20. 18:47

๐Ÿ‘‰ ๋ฌธ์ œ๋งํฌ



๐Ÿ”ธ ๋ฌธ์ œ ๋ถ„์„ ๐Ÿ”ธ

  • N x M ์ง์‚ฌ๊ฐํ˜• ๋•…์— ์ˆ˜์˜์žฅ์„ ๋งŒ๋“ ๋‹ค. ๊ฒฉ์ž ์† ์ˆซ์ž๊ฐ€ ํ•ด๋‹น ๋•…์˜ ๋†’์ด์ด๋‹ค.
  • ๋ฌผ์„ ์ฑ„์›Œ์•ผ ํ•˜๋Š”๋ฐ, ๋ฌผ์€ ์ƒํ•˜์ขŒ์šฐ ๋†’์€ ๊ณณ์—์„œ ๋‚ฎ์€ ๊ณณ์œผ๋กœ๋งŒ ํ๋ฅด๊ณ  ๊ฒฉ์ž ๋ฐ–์œผ๋กœ๋Š” ๋ฌดํ•œ์ • ํ˜๋Ÿฌ๋‚˜๊ฐ€ ๋ฒ„๋ฆฐ๋‹ค.
  • ์ฑ„์šธ ์ˆ˜ ์žˆ๋Š” ๋ฌผ์˜ ์–‘์˜ ์ตœ๋Œ€๊ฐ’์„ ์ถœ๋ ฅํ•œ๋‹ค.

๐Ÿ”ธ ๋ฌธ์ œ ํ’€์ด ๐Ÿ”ธ

  1. ์ƒํ•˜์ขŒ์šฐ ์ธ์ ‘ ๋•…์œผ๋กœ ํ๋ฅด๋Š” ๋ฌผ์˜ ์ด๋™์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ BFS๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  2. ์™ธ๊ฐ์— ๋ถ™์€ ๋•…์€ ๋ฌผ์ด ๊ณ ์ผ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์—ญ๋ฐฉํ–ฅ BFS๋ฅผ ํ†ตํ•ด ์ด์–ด์ง„ ๋•…๋“ค์„ ๋ชจ๋‘ ์ฒดํฌํ•œ๋‹ค.
  3. ๋ฌผ์ด ๊ณ ์ผ ์ˆ˜ ์žˆ๋Š” ๋•…๋“ค์— ๋ฌผ์„ ์ฑ„์šฐ๊ณ  ์ดํ•ฉ์„ ์ถœ๋ ฅํ•œ๋‹ค.
  4. ๋ฌผ ๋†’์ด์˜ ์ตœ๋Œ€๊ฐ’์€ 2๊ฐ€์ง€ ๊ธฐ์ค€์„ ์œ ์˜ํ•ด์„œ ์ •ํ•œ๋‹ค.
    1. ํ•ด๋‹น ๋†’์ด๋ณด๋‹ค ๋†’์•„์ง€๋ฉด ๋ฌผ์ด ํ˜๋Ÿฌ๋‚˜๊ฐ€๋ฒ„๋ฆฌ๋Š” ๊ฒฝ์šฐ : ์ตœ๋Œ€๊ฐ’์˜ ์ธ๋ฑ์Šค๊ฐ€ ์ฒดํฌ๋œ ๊ฒฝ์šฐ
    2. ํ˜๋Ÿฌ๋‚˜๊ฐ€์ง€๋Š” ์•Š์ง€๋งŒ, ๋•…์ด ๋†’์•„์„œ ์กฐ๊ธˆ ๋” ๋†’์ด ๋ฌผ์ด ๊ณ ์ด๋Š” ๊ฒฝ์šฐ : ์ตœ๋Œ€๊ฐ’์˜ ์ธ๋ฑ์Šค๊ฐ€ ์ฒดํฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

๐Ÿ”ธ ์ฝ”๋“œ ๐Ÿ”ธ

import java.io.*;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    private static final int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // ์ƒํ•˜์ขŒ์šฐ
    private static int N, M;
    private static int[][] pool;
    private static boolean[][] visited;

    public static void main(String[] args) throws IOException {
        // Input
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        pool = new int[N][M];
        visited = new boolean[N][M];

        for (int i = 0; i < N; i++) {
            char[] chars = br.readLine().toCharArray();
            for (int j = 0; j < M; j++) {
                pool[i][j] = Character.getNumericValue(chars[j]);
            }
        }

        // BFS 1) ๋ฌผ์„ ๋ถ€์œผ๋ฉด ์•ˆ๋˜๋Š” ๊ณณ์€ true
        for (int i = 0; i < N; i++) {
            if (!visited[i][0]) {
                noWater_Upper(new Point(i, 0));
            }
            if (!visited[i][M - 1]) {
                noWater_Upper(new Point(i, M - 1));
            }
        }
        for (int i = 0; i < M; i++) {
            if (!visited[0][i]) {
                noWater_Upper(new Point(0, i));
            }
            if (!visited[N - 1][i]) {
                noWater_Upper(new Point(N - 1, i));
            }
        }

        // BFS 2) ์ฑ„์šฐ๋Š” ๋ฌผ ์–‘ ์นด์šดํŠธ
        int cnt = 0;
        for (int i = 1; i < N - 1; i++) {
            for (int j = 1; j < M - 1; j++) {
                if (!visited[i][j]) {
                    cnt += cntPoolWater(new Point(i, j));
                }
            }
        }

        // Output
        bw.write(Integer.toString(cnt));
        bw.flush();
    }

    private static void noWater_Upper(Point start) { // ์ƒ์Šน ๋ฐฉํ–ฅ์œผ๋กœ ๋ฌผ์„ ๋ชป ๋‹ด๋Š” ์œ„์น˜ ํ‘œ์‹œ
        Queue<Point> que = new ArrayDeque<>();
        que.add(start);
        visited[start.row][start.col] = true;
        while (!que.isEmpty()) {
            Point p = que.poll();
            for (int[] dir : dir) {
                int row = p.row + dir[0];
                int col = p.col + dir[1];
                if (0 <= row && row < N && 0 <= col && col < M
                        && !visited[row][col] && pool[row][col] >= pool[p.row][p.col]) {
                    visited[row][col] = true;
                    que.add(new Point(row, col));
                }
            }
        }
    }

    private static int cntPoolWater(Point start) { // ๋ฌผ์ด ๊ณ ์ด๋Š” ์ตœ๋Œ€ ๋†’์ด ๋ฐ˜ํ™˜
        int maxHeight = Integer.MAX_VALUE;

        Queue<Point> que = new ArrayDeque<>();
        Queue<Point> water = new ArrayDeque<>();
        boolean[][] flag = new boolean[N][M];

        que.add(start);
        water.add(start);
        flag[start.row][start.col] = true;

        while (!que.isEmpty()) { // ๋ฌผ ๋†’์ด์˜ ์ตœ๋Œ€๊ฐ’ ์ฐพ๊ธฐ
            Point p = que.poll();
            for (int[] dir : dir) {
                int row = p.row + dir[0];
                int col = p.col + dir[1];
                if (visited[row][col]) { // ๋ฌผ์„ ์ฑ„์šฐ๋ฉด ์•ˆ๋˜๋Š” ๊ณณ
                    if (pool[row][col] <= pool[p.row][p.col]) { // ์ฑ„์šฐ๋ฉด ์•ˆ๋˜๋Š” ๊ณณ์ธ๋ฐ ํ˜๋Ÿฌ๊ฐ
                        noWater_Upper(new Point(row, col));
                        return 0;
                    }
                    maxHeight = Math.min(maxHeight, pool[row][col]);
                } else if (!flag[row][col] && pool[row][col] <= pool[p.row][p.col]) { // ์‹œ์ž‘ ์œ„์น˜์— ๋ฌผ ๋ถ€์šฐ๋ฉด ๊ฐ™์ด ์ฐธ
                    flag[row][col] = true;
                    que.add(new Point(row, col));
                    water.add(new Point(row, col));
                } else if (pool[row][col] > pool[p.row][p.col])
                    maxHeight = Math.min(maxHeight, pool[row][col]);
            }
        }

        int cnt = 0;
        for (Point p : water) {
            if (maxHeight > pool[p.row][p.col]) {
                cnt += maxHeight - pool[p.row][p.col];
                pool[p.row][p.col] = maxHeight;
            }
        }

        return cnt;
    }

    private static class Point {
        int row, col;

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

๐Ÿ”ธ ์ฝ”๋“œ ํ•ด์„ ๐Ÿ”ธ

  • N x M ๋•…์˜ ํ…Œ๋‘๋ฆฌ๋Š” ๋ฌผ์ด ํ˜๋Ÿฌ๋‚˜๊ฐ€๋ฒ„๋ฆฐ๋‹ค. ๋ฌผ์ด ํ˜๋Ÿฌ ๋“ค์–ด์˜ค๋Š” ๋•…๋“ค๋„ ๋ชจ๋‘ ๋ฌผ์„ ์ฑ„์šฐ๋ฉด ์•ˆ๋˜๋Š” ๋•…์ด๋ฏ€๋กœ ์—ญ๋ฐฉํ–ฅ BFS๋ฅผ ๊ตฌํ˜„ํ•œ noWater_Upper() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด visited๋ฅผ true๋กœ ์ฒดํฌํ•œ๋‹ค.
  • visited๊ฐ€ false์ธ ๋‚˜๋จธ์ง€ ๋•…๋“ค์— cntPoolWater() ๋ฉ”์„œ๋“œ๋กœ ๋ฌผ์„ ์ฑ„์šด๋‹ค.
    • ์‹œ์ž‘ ์œ„์น˜์—์„œ ๊ฐ™๊ฑฐ๋‚˜ ์ž‘์€ ๋†’์ด๋กœ ์ด์–ด์ง„ ๋•…๋“ค์„ water ํ์— ๋„ฃ๋Š”๋‹ค.
    • ์ด๋•Œ ์ฃผ๋ณ€ ๋•…์˜ ๋†’์ด ์ค‘ ๊ฐ€์žฅ ๋‚ฎ์€ ๊ฐ’์„ max์— ์ €์žฅํ•œ๋‹ค.
    • ํƒ์ƒ‰์ด ๋๋‚˜๋ฉด, water์— ์ €์žฅ ๋œ ๋•…๋“ค์— max ๋งŒํผ ๋ฌผ์„ ์ฑ„์šด๋‹ค.

๐Ÿ”ธ end ๐Ÿ”ธ

  • ์ƒ๋‹นํžˆ ์–ด๋ ค์› ๊ณ  ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฐ ๋ฌธ์ œ์ด๋‹ค. BFS๋ฅผ 2์ข…๋ฅ˜๋กœ ๋‚˜๋ˆ ์„œ ํ•˜๊ณ  ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค๋Š” ์•„์ด๋””์–ด๋Š” ๊ธˆ๋ฐฉ ๋‚˜์™”๋Š”๋ฐ, ๊ตฌ์ƒ์„ ์กฐ๊ธˆ ์ด์ƒํ•˜๊ฒŒ ํ•ด์„œ ํ…Œ์ผ€๋ฅผ ๋งŽ์ด ๋งŒ๋“ค์—ˆ์–ด์•ผ ํ–ˆ๋‹ค.
  • ๋ฌผ์„ ์ฑ„์šฐ๋Š” cntPoolWater() ๋ฉ”์„œ๋“œ์˜ BFS์—์„œ ํƒ์ƒ‰ ๋ฒ”์œ„๋ฅผ visited๊ฐ€ false ๊ฒฝ์šฐ๋กœ๋งŒ ๋’€์—ˆ๋Š”๋ฐ, ๋•…์˜ ๋†’์ด๊ฐ€ ๊ฐ–๊ฑฐ๋‚˜ ๋‚ฎ์€ ๊ฒฝ์šฐ๋ผ๋Š” ์กฐ๊ฑด๋„ ์ถ”๊ฐ€๋กœ ํ•„์š”ํ–ˆ๋‹ค.
  • ํ•œ ๋ฒˆ ํƒ์ƒ‰ํ•œ ๋•…์€ ๋ฐฐ์ œํ•˜๋ ค๊ณ  ํ–ˆ๋˜๊ฒŒ ํฐ ์˜ค์ ์ด์—ˆ๋Š”๋ฐ, ๊ฐ™์€ ์นธ์ด์–ด๋„ ๋ฌผ์„ ์—ฌ๋Ÿฌ๋ฒˆ ๋†’์—ฌ๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฐ”๊พธ์–ด์„œ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.
  • ์ฝ”๋“œ ๋””๋ฒ„๊น…์— ์‹œ๊ฐ„์ด ๋„ˆ๋ฌด ๊ฑธ๋ ค์„œ ๋ฆฌํŒฉํ„ฐ๋ง์€ ํฌ๊ธฐํ•˜๊ณ  ์ข€ ์ง€์ €๋ถ„ํ•œ ํ˜•ํƒœ์˜ ๋‹ต์•ˆ์œผ๋กœ ๋งˆ๋ฌด๋ฆฌ๋˜์—ˆ๋‹ค...
728x90