Problem Statement
There are N buildings in a certain two-dimensional landscape. Each building has a height given by hi,i∈[1,N] . If you join K adjacent buildings, they will form a solid rectangle of area K×min(hi,hi+1,…,hi+k−1) .
Given N buildings, find the greatest such solid area formed by consecutive buildings.
Input Format
The first line contains
N
, the number of buildings altogether.
The second line contains
N
space-separated integers, each representing the height of a building.
Constraints
1≤N≤105
1≤hi≤106
Output Format
One integer representing the maximum area of rectangle formed.
Sample Input
5
1 2 3 4 5
Sample Output
9
Explanation
An illustration of the test case follows.
.
#include<stdio.h> //Largest Rectangle
#include<string.h>
#include<stdlib.h>
#define MAXN 100001
#define MAXH 1000001
/*
算法思想:
对于数组中的每一个元素a[i],计算以a[i]作为最小值的矩形的面积area,求出最大的面积即可。
为了计算以a[i]作为最小值的矩形的面积,我们需要知道a[i]之前第一个比a[i]小的元素索引(leftindex)以及a[i]之后第一个比a[i]小
的元素索引(rightindex),这样以[i]作为最小值的矩形的面积即为a[i]*(前后索引之间的距离)
利用数据结构栈(栈内元素递增),将数组元素依次与栈顶元素比较,当栈空时,直接入栈,当栈顶元素小于等于数组元素时,数组元素
直接入栈,否则,栈顶元素出栈直至栈顶元素小于等于数组元素,再将数组元素入栈。当所有元素都遍历过之后,若栈非空,则一次弹栈,
并计算相应的面积,直至栈空即可
为了能够知道a[i]的leftindex和rightindex,在数组元素入栈时需要记录元素的索引
*/
int a[MAXN], stack[MAXN];
int top = -1;
int area[MAXN]; //记录以元素a[i]为最小值的矩形的面积
int index[MAXN]; //记录栈中元素的原来序号(即A[i]的i)
int FindMax(int n)
{
int i, leftindex, rightindex, max=0;
for (i = 0; i < n; i++)
{
if (top < 0 || (top >= 0 && stack[top]<=a[i])) //直接入栈
{
stack[++top] = a[i];
index[top] = i;
}
else
{
while (top >= 0 && stack[top] > a[i])
{
//计算以栈顶元素作为最小值的矩形的面积
//top>0时,right即为i,leftindex为栈顶元素之前元素的索引,即index[top-1]
//top==0时,rightindex和rightindex之间的距离即为i
area[index[top]] = stack[top] * (top > 0 ? (i - index[top - 1] - 1) : i);
if (max < area[index[top]]) max = area[index[top]]; //找最大
top--;
}
stack[++top] = a[i];
index[top] = i;
}
}
while (top >= 0) //数组元素遍历完毕,若栈非空,则将栈中元素依次出栈,并计算相应的面积
{
area[index[top]] = stack[top] * (top > 0 ? (i - index[top - 1] - 1) : i);
if (max < area[index[top]]) max = area[index[top]];
top--;
}
return max;
}
int main()
{
int n, i;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", a + i);
printf("%d\n", FindMax(n));
return 0;
}