
해당 문제는 초기설계를 잘못 잡아서 고생했다가 로직을 갈고 성공했다.
모든 벽을 한 번씩만 방문하여 빗물 계산하기!
일단 나는 빗물의 형태를 다음과 같이 나누었다.
-> 참고로 평행은 오름차순과 동일한 로직으로 빗물을 계산해주었다.

빗물을 계산해주는 방법은 다음과 같다.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int RAIN = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
String[] W = br.readLine().split(" ");
int[] wall = new int[W.length];
for (int i = 0; i < W.length; i++) {
wall[i] = Integer.parseInt(W[i]);
}
for(int i=0;i<wall.length-1; i++){
i = CheckRain(i, wall);
}
System.out.println(RAIN);
}
public static int CheckRain(int start, int[] wall) {
int sumBlock = 0;
int highest = 0;
int move = 0;
int i = start + 1;
for (; i < wall.length && wall[start] > wall[i]; i++) {
highest = Math.max(highest, wall[i]);
if(highest > wall[i]) continue;
move++;
sumBlock+=wall[i];
}
if(i==wall.length) i--;
highest = Math.max(highest,wall[i]);
highest = Math.min(wall[start], highest); //내림차순의 경우 정확한 highest 계산 위한 코드
if(wall[start] >= wall[highest]&&highest!=0) {
sumBlock -= highest;
move-=1;
}
RAIN += highest*move - sumBlock;
return start+move+1;
}
}
그러나ㅠ 빗물에 대한 2가지 형태를 하나의 for문으로 수행하고자 하니 수없이 생기는 if문들과 반례들로 인해 해당 로직은 구현하지 못하였다😢
그래서 새롭게 로직을 갈게 되었다
빗물의 형태는 초기 설계와 같다.
⭐ 내림차순->오름차순의 경우는 없다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int RAIN = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
String[] W = br.readLine().split(" ");
int[] wall = new int[W.length];
int Biggest = 0;
int BiggestIndex = 0;
for (int i = 0; i < W.length; i++) {
wall[i] = Integer.parseInt(W[i]);
if(wall[i]>=Biggest) {
Biggest=wall[i];
BiggestIndex = i; //가장 큰 값을 가지게 될 값의 제일 마지막 인덱스 저장
}
}
CheckRain(BiggestIndex, wall); //순방향 체크
CheckRainReverse(BiggestIndex, wall); //역순으로 체크
System.out.println(RAIN);
}
public static void CheckRain(int BiggestIndex, int[] wall) { //오름차순 형태 계산
for(int i=0; i<BiggestIndex; i++){
if(wall[i]>wall[i+1]){
RAIN += wall[i]-wall[i+1];
wall[i+1] = wall[i];
}
}
}
public static void CheckRainReverse(int BiggestIndex, int[] wall) { //내림차순 형태 계산
for(int i= wall.length-1; i>BiggestIndex; i--){
if(wall[i]>wall[i-1]){
RAIN += wall[i]-wall[i-1];
wall[i-1] = wall[i];
}
}
}
}
O(n)이다.
로직을 바꾸니 너무 단시간에 성공해서 허무했다. 초기 설계는 중요하다는 걸 다시 느꼈다~