빗물
문제
2차원 세계에 블록이 쌓여있다. 비가 오면 블록 사이에 빗물이 고인다.
비는 충분히 많이 온다. 고이는 빗물의 총량은 얼마일까?
입력
첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500)
두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치부터 차례대로 W개 주어진다.
따라서 블록 내부의 빈 공간이 생길 수 없다. 또 2차원 세계의 바닥은 항상 막혀있다고 가정하여도 좋다.
출력
2차원 세계에서는 한 칸의 용량은 1이다. 고이는 빗물의 총량을 출력하여라.
빗물이 전혀 고이지 않을 경우 0을 출력하여라.
풀이
사람의 입장에서 이 문제를 풀려면 그림을 그림으로써 쉽게 계산할 수 있지만, 우리는 컴퓨터의 입장에서 생각해야한다.
이를 수식으로 풀어보기 위해서는 어느 특정 위치에서 담기는 빗물의 양을 알아야한다.
빗물의 양은 어떻게 될까?
- 시작점과, 끝점은 빗물이 담길 수 없다.
- 양 끝점을 제외하면 자신의 위치를 기준으로 왼쪽에 있는 블록의 최댓값과 오른쪽에 있는 최댓값중 더 작은 값에서 자신 위치 블록값을 뺀 값만큼 고이게 된다.
-> 즉 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 |