14719번: 빗물
(1:00)
빗물이 고이기 위해서는 움푹 파인 곳이 필요하다.
움푹 파인 곳이라는 것은 이런식으로 감싸지는 곳이다.
◼◻◻◼
◼◼◻◼
◼◼◼◼
//3
그리고 예시를 통해
0 0 0 2 0
◻◻◻◻◻
◻◻◻◼◻
◻◻◻◼◻
//0
이런 경우는 고인 곳이 없다는 것이니,막히지 않았다면
고일 수 없음을 의미함을 알 수 있다.
즉 아래의 경우도 정답은 0이다
◼◻◻◻
◼◼◻◻
◼◼◼◻
여전히 잘 못한다는 것이 느껴졌다.
완전탐색?
h(cur-1) < h(cur) 인 때 , cur의 좌측에서의 고인 물의 높이를 구할 수 있다.
◼◻◻◻◼
◼◼◻◻◼
◼◼◼◻◼
◼◻◻◻◻◻
◼◼◻◻◻◼
◼◼◻◼◻◼
◼◼◻◼◻◼
4 6
4 3 0 2 0 3
◼◻◻◻◻◻
◼◼◼◼◼◼
◼◼◼◼◼◼
◼◼◼◼◼◼
4 6
4 3 3 3 3 3
// 그런데 이런 경우도 풀기 위하여
// 이미 계산한 곳은 칸을 채우도록 한다
◼◻◻◻◻◻
◼◻◻◻◻◻
◼◼◻◻◻◻
◼◼◻◻◻◼
4 6
4 2 0 0 0 1
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static int tr,tc;
public static int[] h = new int[500];
public static int acc=0;
public static void solve(){
//boolean reserv=false;
// for 문 조건상 자동으로, tc가 1인 경우에는 0이 된다.
for(int i=1;i<tc;i++) {
if (h[i] > h[i - 1] ) {
//빗물을 구한다.
accum(i);
}
}
}
public static void accum(int cur){
int pre = cur-1;
int left =0;
while(true){
if(pre==0||h[cur]<=h[pre] ||h[pre-1]<h[pre])break;
pre--;
}
// cur을 right bound, pre를 left bound라고 한다.
// 이 둘 중 작은 값으로, 빗물이 채워지고 -> 빗물을 채운다.
left = pre;
int limit = Math.min(h[cur],h[left]);
for(pre=left+1;pre<cur;pre++) {
acc += (limit - h[pre]);
//
h[pre] = limit;
}
}
public static void Setting() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
tr = Integer.parseInt(st.nextToken());
tc = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
for(int i=0;i<tc;i++){
h[i] = Integer.parseInt(st.nextToken());
}
}
public static void main(String[] args) throws IOException {
Setting();
solve();
System.out.println(acc);
}
}