最大长(正)方形
给定从左到右多个矩形,已知这此矩形的宽度都为1,长度不完全相等。这些矩形相连排成一排,求在这些矩形包括的范围内能得到的面积最大的矩形,打印出该面积。所求矩形可以横跨多个矩形,但不能超出原有矩形所确定的范围。
建立一个单调递增栈,所有元素各进栈和出栈一次即可。每个元素出栈的时候更新最大的矩形面积。
设栈内的元素为一个二元组(x, y),x表示矩形的高度,y表示矩形的宽度。
若原始矩形高度分别为2,1,4,5,1,3,3
高度为2的元素进栈,当前栈为(2,1)
高度为1的元素准备进栈,但必须从栈顶开始删除高度大于或等于1的矩形,因为2已经不可能延续到当前矩形。删除(2,1)这个元素之后,更新最大矩形面积为2*1=2,然后把它的宽度1累加到当前高度为1的准备进栈的矩形,然后进栈,当前栈为(1,2)
高度为4的元素进栈,当前栈为(1,2) (4,1)
高度为5的元素进栈,当前栈为(1,2) (4,1) (5,1)
高度为1的元素准备进栈,删除(5,1)这个元素,更新最大矩形面积为5*1=5,把1累加到下一个元素,得到(4,2),删除(4,2),更新最大矩形面积为4*2=8,把2累加到下一个元素,得到(1,4),1*4=4<8,不必更新,删除(1,4),把4累加到当前准备进栈的元素然后进栈,当前栈为(1,5)
高度为3的元素进栈,当前栈为(1,5) (3,1)
高度为3的元素准备进栈,删除(3,1),不必更新,把1累加到当前准备进栈的元素然后进栈,当前栈为(1,5) (3,2)
把余下的元素逐个出栈,(3,2)出栈,不必更新,把2累加到下一个元素,当前栈为(1,7),(1,7)出栈,不必更新。栈空,结束。
最后的答案就是8。
//题目中tmp的作用:
//因为元素出栈的时候,根据我们的思想,要进站的元素可以向前延伸
//出栈元素的前面的元素可以向后延伸
//所以我们要设一个tmp来记录向前,向后延伸的长度
//而且两者延伸的长度有关系(具体关系请大家自己思考代码)
//本题重难点:tmp的意义!
#include<stdio.h>
struct
{
long long h;
long long l;
} cf[100010]; //直接用结构体模拟链表(省的再开一个数组了)
int main()
{
long long n;
while(scanf("%lld",&n)!=EOF)
{
if(n==0)
{
break;
}
long long h; //由于int longlong 交叉非常的烦,我就全部用longlong了
long long top=0;
long long s=0;
long long tmp;
for(long long i=1; i<=n; i++)
{
scanf("%lld",&h);
tmp=0; //注意,小小的tmp必不可少,很重要!
while(h<=cf[top-1].h&&top>0)
{
if(s<cf[top-1].h*(cf[top-1].l+tmp)) //出栈的时候顺带更新最大长方形的值!
{
s=cf[top-1].h*(cf[top-1].l+tmp);
}
tmp+=cf[top-1].l; //tmp加上出栈元素的宽
top--;
}
cf[top].h=h;
cf[top].l=1+tmp; //入栈
top++;
}
tmp=0;
while(top>0) //把最后没有出栈的元素全部出栈了
{
if(s<cf[top-1].h*(cf[top-1].l+tmp))//这步和上面的原理相似
{
s=cf[top-1].h*(cf[top-1].l+tmp);
}
tmp+=cf[top-1].l;
top--;
}
printf("%lld\n",s);
}
}
//题目中tmp的作用:
//因为元素出栈的时候,根据我们的思想,要进站的元素可以向前延伸
//出栈元素的前面的元素可以向后延伸
//所以我们要设一个tmp来记录向前,向后延伸的长度
//而且两者延伸的长度有关系(具体关系请大家自己思考代码)
//本题重难点:tmp的意义!
#include<stdio.h>
struct
{
long long h;
long long l;
} cf[100010]; //直接用结构体模拟链表(省的再开一个数组了)
int main()
{
long long n;
while(scanf("%lld",&n)!=EOF)
{
if(n==-1)
{
break;
}
long long h,l; //由于int longlong 交叉非常的烦,我就全部用longlong了
long long top=0;
long long s=0;
long long tmp;
for(long long i=1; i<=n; i++)
{
scanf("%lld%lld",&l,&h);
tmp=0; //注意,小小的tmp必不可少,很重要!
while(h<=cf[top-1].h&&top>0)
{
if(s<cf[top-1].h*(cf[top-1].l+tmp)) //出栈的时候顺带更新最大长方形的值!
{
s=cf[top-1].h*(cf[top-1].l+tmp);
}
tmp+=cf[top-1].l; //tmp加上出栈元素的宽
top--;
}
cf[top].h=h;
cf[top].l=l+tmp; //入栈
top++;
}
tmp=0;
while(top>0) //把最后没有出栈的元素全部出栈了
{
if(s<cf[top-1].h*(cf[top-1].l+tmp))//这步和上面的原理相似
{
s=cf[top-1].h*(cf[top-1].l+tmp);
}
tmp+=cf[top-1].l;
top--;
}
printf("%lld\n",s);
}
}