Week5 A - 最大矩形
给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。
Input
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,你可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。
Output
对于每组测试数据输出一行一个整数表示答案。
Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Sample Output
8
4000
解题思路
利用单调递增栈 单调递减栈 由左至右 由右至左
单调栈实现 : 若要插入的值不满足当前最上层元素的值 将最上层元素推出 重复检验至最上层元素满足将要插入值 再将值插入
遍历出每个点左边与右边第一个出现比自身小的点记录在数组中 使得这个点是这段范围内最矮的
最后利用每个点的左右范围乘上自身高度
注意
输出时数据很大要用 long long 或是一开始将所有变量设 long long
用 scanf 比较不容易TL
Code
#include<iostream>
#include<stack>
using namespace std;
int p[101000];
int pl[101000];
int pr[101000];
int main(){
int t=0;
while(scanf("%d",&t)){
if(t==0)break;
stack<int> st;
long long ans=0;
for(int i=1;i<=t;i++){
cin>>p[i];
pl[i]=t+1;
}
for(int i=1;i<=t+1;i++){
while(st.size()>0&&p[st.top()]>p[i]){
pl[st.top()]=i;
st.pop();
}
st.push(i);
}
for(int i=t;i>=0;i--){
while(st.size()>0&&p[st.top()]>p[i]){
pr[st.top()]=i;
st.pop();
}
st.push(i);
}
for(int i=1;i<=t;i++){
//cout<<pr[i]<<' '<<pl[i]<<endl;
if((long long)p[i]*(pl[i]-pr[i]-1)>ans)ans=(long long)p[i]*(pl[i]-pr[i]-1);
}
cout<<ans<<endl;
}
}