본문 바로가기

알고리즘

14719 빗물 (Java)

빗물

문제

2차원 세계에 블록이 쌓여있다. 비가 오면 블록 사이에 빗물이 고인다.

비는 충분히 많이 온다. 고이는 빗물의 총량은 얼마일까?

입력

첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500)

두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치부터 차례대로 W개 주어진다.

따라서 블록 내부의 빈 공간이 생길 수 없다. 또 2차원 세계의 바닥은 항상 막혀있다고 가정하여도 좋다.

출력

2차원 세계에서는 한 칸의 용량은 1이다. 고이는 빗물의 총량을 출력하여라.

빗물이 전혀 고이지 않을 경우 0을 출력하여라.

풀이

사람의 입장에서 이 문제를 풀려면 그림을 그림으로써 쉽게 계산할 수 있지만, 우리는 컴퓨터의 입장에서 생각해야한다.
이를 수식으로 풀어보기 위해서는 어느 특정 위치에서 담기는 빗물의 양을 알아야한다.
빗물의 양은 어떻게 될까?

  1. 시작점과, 끝점은 빗물이 담길 수 없다.
  2. 양 끝점을 제외하면 자신의 위치를 기준으로 왼쪽에 있는 블록의 최댓값과 오른쪽에 있는 최댓값중 더 작은 값에서 자신 위치 블록값을 뺀 값만큼 고이게 된다.
    -> 즉 i번째 고이게 되는 빗물의 양 = min( max(블록의 크기(0~i - 1) , max(블록의 크기(i+1 ~ w)) - 블록의크기[i] 이다.

코드

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

public class Main{

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int h = Integer.parseInt(st.nextToken());
        int w = Integer.parseInt(st.nextToken());

        int[] arr = new int[w];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < w; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int ans = 0;
        // 처음과 마지막은 물이 담길 수 없다.
        for (int i = 1; i < w - 1; i++) {
            int leftMaxHeight = 0;
            int rightMaxHeight = 0;

            // 현재 위치를 기준으로 왼쪽에서 최댓값 구하기
            for (int l = 0; l < i; l++) {
                leftMaxHeight = Math.max(leftMaxHeight, arr[l]);
            }

            // 현재 위치를 기준으로 오른쪽에서 최댓값 구하기
            for (int r = i + 1; r < w; r++) {
                rightMaxHeight = Math.max(rightMaxHeight, arr[r]);
            }

            int maxHeight = Math.min(rightMaxHeight, leftMaxHeight);
            if (maxHeight > arr[i]) {
                ans += maxHeight - arr[i];
            }
        }

        System.out.println(ans);

    }


}

'알고리즘' 카테고리의 다른 글

1700 멀티탭 스케줄링 (Java)  (0) 2022.05.20
1806 부분합 (Java)  (0) 2022.05.19
3079 입국심사 (Java)  (0) 2022.05.13
1477 휴게소 세우기 (Java)  (0) 2022.05.13
14503 로봇 청소기 (Java)  (0) 2022.05.04