题目
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.
Input
The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, …, hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.
Output
For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.
Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Sample Output
8
4000
- 双向判断,以当前高度向左向右延伸(当左边高度大于等于当前高度时向左延伸,l数组记录向左延伸到哪里;当右边高度大于等于当前高度时向右延伸,r数组记录向右延伸到哪里),最右减最左再乘以当前高度就是该高度的最大面积
- 此代码中设st数组为栈,设栈中元素从上到下的值为xi>xi+1且 hxi>hxi+1(我实在是不会在这里面输入下标啊),st数组帮助判断可以向左或向右延伸多少(这里很重要,要好好理解一下)
- 代码来源于《挑战程序设计竞赛》
#include <stdio.h>
#include <string.h>
#include <stack>
#include <algorithm>
using namespace std;
int n,h[100010],l[100010],r[100010],st[100010];
void solve()
{
int t=0;
for(int i=0;i<n;i++) //计算l数组
{
while(t>0&&h[st[t-1]]>=h[i])
t--;
l[i]=t==0?0:(st[t-1]+1); //t==0,栈为空,左边高度均大于等于当前元素的高度,可以延伸到最左边,否则根据st数组计算可以延伸的长度
st[t++]=i;
}
t=0;
for(int i=n-1;i>=0;i--) //计算r数组
{
while(t>0&&h[st[t-1]]>=h[i])
t--;
r[i]=t==0?(n-1):(st[t-1]-1);
st[t++]=i;
}
long long c=0;
for(int i=0;i<n;i++)
c=max(c,(long long)h[i]*(r[i]-l[i]+1)); //加1是因为要加上他自己,否则只有左边的和右边的
printf("%lld\n",c);
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0;i<n;i++)
scanf("%d",&h[i]);
solve();
}
return 0;
}