1574. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
例如,当给定数字序列为 0,1,0,2,1,0,1,3,2,1,2,1
时,柱子高度图如下所示,最多可以接 6 个单位的雨水。
输入格式
第一行包含整数 n。
第二行包含 n 个非负整数。
输出格式
输出一个整数,表示最大接水量。
数据范围
1≤n≤105,
序列中元素均不大于 1000。
输入样例:
12
0 1 0 2 1 0 1 3 2 1 2 1
输出样例:
6
代码1:
/*
填满水之后找到其中最高点,最高点的左边部分从左到右,一定是不严格递增的,右边从右到左也是不严格递增的
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
int h[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> h[i];
//找到最高点的下标
int pos = max_element(h + 1, h + 1 + n) - h - 1;
int sum = 0;
//从左向右遍历,若不满足递增的性质,则补上
int temp = h[1];
for (int i = 1; i < pos; i++)
{
if (h[i] < temp)
sum += temp - h[i];
else
temp = h[i];
}
//从右向左遍历,若不满足递增的性质,则补上
temp = h[n];
for (int i = n; i > pos; i--)
{
if (h[i] < temp)
sum += temp - h[i];
else
temp = h[i];
}
cout << sum;
return 0;
}
代码2:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5;
int h[N]; // h为障碍物高度,q为单调栈
int q[N]; // h[q[tt]]表示序号为q[tt]的障碍物的高度
int tt = 0; // tt为栈顶指针,q[tt]为障碍物序号
int res = 0;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> h[i];
for (int i = 1; i <= n; i++)
{
int last = 0; //储存上一个高度
while (tt > 0 && h[q[tt]] < h[i]) //判断栈不为空且栈顶元素小于等于当前元素时
{
//最近的一个产生不了雨水
res += (h[q[tt]] - last) * (i - 1 - q[tt]);
last = h[q[tt]];
tt--;
}
//若栈不为空则将插入元素和最后一个出栈元素的做差f
if (tt > 0)
res += (h[i] - last) * (i - 1 - q[tt]);
q[++tt] = i; //当前障碍物入栈
}
cout << res;
return 0;
}