每日一题】7月24日小A的柱状图
小A的柱状图
https://ac.nowcoder.com/acm/problem/23619
题意
现在有一个柱状图,告诉你每一个,柱子的宽度和高度,然后问你这个图里最大的矩形面积,这里的矩形可以是这样的
也可以是这样的
这样就很好理解了。就是找其中出现了的最大的矩形。
解析
这个题目用到了单调栈这个数据结构,简单描述一下就是栈里面的元素呈单调递增或者单调递减,并不难理解,如果是递增的,那么栈顶元素即是最大的,这个题目为什么用这个,举个例子
像这样的一个柱状图,我们肯定要穷举每一个可能组成的矩形然后来比较大小,我们可以从最左边开始,
第一列
第二列
到了第三列
就要比较这两个了
第四列也是这样
那么到了第五列呢,第五列比前面的更矮,我们在记录前面的最大值之后,在第五列(如果后面还有)就用不到第五列前并且比第五列高的地方了,因为第五列只能和他一样高的组成矩形,比他高或者比他矮都不行
那么我们现在在储存的时候,在计算完最大值之后,遇到了更矮的,前面的高的就没必要存下来了,这样子就形成了一个单调增的栈,(为什么是栈,因为比他高的都依次出栈,然后把他作为最高的)
然后我们只要手写一个栈,模拟进栈出栈就好了,
遇到比栈顶高的和他相同的直接压进栈,遇到比他矮的就将栈里比他高的全部出栈,然后维护一下宽度就好了
有一个点要注意,就是在最后一个之后再压一个0进栈,因为如果最后几个是递增或者相同的情况,在我的代码里是有问题的,我的代码里如果没有元素出栈就不会去计算矩阵的大小,
ps:数据有点太弱了,最好不压一个0进栈也能过,一开始我看大佬的代码还以为是我的理解错了。。。。结果是大佬的笔误。。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e6+7;
ll w[MAXN],h[MAXN];
ll st_h[MAXN],st_w[MAXN],top;
int main(void){
int n,m;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lld",&w[i]);
for(int i=1;i<=n;++i)
scanf("%lld",&h[i]);
h[n+1]=w[n+1]=top=0;
ll ans=0;
for(int i=1;i<=n+1;++i){
if(h[i]>=st_h[top]){
top++;
st_h[top]=h[i];
st_w[top]=w[i];
}
else{
ll width=0;
while(top && h[i]<=st_h[top]){
width+=st_w[top];
ans=max(ans,width*st_h[top]);
top--;
}
top++;
st_h[top]=h[i];
st_w[top]=width+w[i];
}
}
printf("%lld\n",ans);
return 0;
}每日一题 文章被收录于专栏
写每日一题呀
查看13道真题和解析