Algorithm/BOJ
[백준 14719] 빗물
giiro
2020. 11. 1. 00:11
문제
14719번: 빗물
첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500) 두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치
www.acmicpc.net
풀이
1. 어떤 칸에 빗물이 채워지는 조건에 대해서 생각해볼 때, 그 칸을 제외한 (좌측의 최대 높이, 우측의 최대 높이) 둘 중 작은 높이에서 어떤 칸의 높이를 뺀 만큼 채워진다는 걸 알 수 있습니다. (물론 물이 채워져야 하므로 좌측의 최대 높이, 우측의 최대 높이는 어떤 칸의 높이보다 높아야 합니다.)
2. i칸을 제외한 i칸 좌측의 최대 높이를 $pre[i]$, 우측의 최대높이를 $suf[i]$라고 할 때, 그 의미대로 아래와 같이 표현할 수 있습니다.
$pre[i] = max(pre[i - 1], v[i - 1]) (단, 1<= i < w - 1)$
$suf[i] = max(suf[i + 1], v[i + 1]) (단, 1 <= i < w - 1)$
코드
#include <bits/stdc++.h>
using namespace std;
int h, w, ans;
vector<int> v, pre, suf;
int main() {
cin.tie(NULL); cout.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> h >> w;
v.resize(w), pre.resize(w), suf.resize(w);
for (int i = 0; i < w; i++) cin >> v[i];
pre[0] = v[0];
for (int i = 1; i < w - 1; i++)
pre[i] = max(pre[i - 1], v[i - 1]);
suf[w - 1] = v[w - 1];
for (int i = w - 2; i >= 1; i--)
suf[i] = max(suf[i + 1], v[i + 1]);
for (int i = 1; i < w - 1; i++)
if (pre[i] > v[i] && suf[i] > v[i])
ans += min(pre[i], suf[i]) - v[i];
cout << ans;
}