A - 最大矩形
-
题意:
给一个直方图,求直方图中的最大矩形的面积。例如,下面这个图片中直方图的高度从左到右分别是2, 1, 4, 5, 1, 3, 3, 他们的宽都是1,其中最大的矩形是阴影部分。
-
输入输出:
Input
输入包含多组数据。每组数据用一个整数n来表示直方图中小矩形的个数,你可以假定1 <= n <= 100000. 然后接下来n个整数h1, …, hn, 满足 0 <= hi <= 1000000000. 这些数字表示直方图中从左到右每个小矩形的高度,每个小矩形的宽度为1。 测试数据以0结尾。
Output
对于每组测试数据输出一行一个整数表示答案。
-
解题思路:
本题为单调栈问题的经典例题,要求最大面积,即要求当前的高和所能延伸的最大的宽的乘积的最大值。
定义long long型数组存储高度,声明int类型的栈st,遍历数组,当栈为空或是即将入栈的元素大于栈顶元素时,满足单调栈的条件,将当前元素入栈。当即将入栈的元素大于栈顶元素时,将栈顶元素弹出栈直到栈顶元素小于即将入栈的元素。弹出同时计算当前面积:弹出栈的元素的高和所能延伸的最大宽的乘积,因为单调栈中记录的是编号,所以(top-i)就是最大的宽。新元素入栈时要更新a[top]的值作为下一次的起点,ans记录当前最大面积。将a[n]的值定为-1,确保数组遍历结束后栈内元素可以被清空。 -
代码实现:
#include <iostream>
#include <stack>
using namespace std;
long long a[100010];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
while(cin>>n)
{
if(n==0) break;
long long top,ans,num;
stack <int> st;
for(int i=0;i<n;i++)
cin>>a[i];
ans=0;
a[n]=-1;
for(int i=0;i<=n;i++)
{
if(st.empty()||a[i]>=a[st.top()])
st.push(i);
else
{
while(!st.empty()&&a[i]<a[st.top()])
{
top=st.top();
st.pop();
num=(i-top)*a[top];
if(num>ans)
ans=num;
}
st.push(top);
a[top]=a[i];
}
}
cout<<ans<<endl;
}
return 0;
}