ZCMU-1677-小学生小明,圣光会制裁你!!!

1677: 小学生小明,圣光会制裁你!!!

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 59   Solved: 22
[ Submit][ Status][ Web Board]

Description

一个数轴上连续摆放着n个矩形,每个矩形的底边占一个单位的长度,第i个矩形的高度为ai.小明想从这n个矩形围成的图形割出一块面积最大的矩形,他已经机智的割出了最大矩形,然而他并不知道矩形面积怎么算,于是他就想问你最大矩形面积怎么算。

Input

多组测试数据。

第一行输入n(0<n<=100000)当n=0时停止输入

接下一行来输入n个数ai,0<=ai<=1000000000

Output

输出最大矩形面积

Sample Input

7 2 1 4 5 1 3 3
4 1000 1000 1000 10000

Sample Output

8
4000

【解析】
这道题的话网上是用栈来做的,自己一看确实这样做比较方便。很多题都是这样..不过自己感觉总是做了忘..做了
忘也希望有点积累吧。这道题我们想啊,怎么样可以凑出一个矩形来 ,矩形的高度和宽度要怎么选择,大家可以这
么选,一高一矮的矩形在一起肯定是选矮的矩形高度来作为最大面积矩形的高度,还是在代码中解释吧..感觉有点
卡词了...这里需要用到pair,如果之前不理解的可以去了解一下...
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<stack>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> P;
#define MAX 100010
int main()
{
    int n,i;
    LL sum,height,H,W;
    while(~scanf("%d",&n))
    {
        if(n==0)
            break;
        stack<P>a;//模拟栈
        sum=0;
        for(i=0;i<n;i++)
        {
            scanf("%lld",&height);//输入高度
            LL width=0;
            while(!a.empty()&&a.top().first>=height)/*如果栈顶的元素高于输入的高度就要开始计算
                左边界和右边界也可以就行确定,拿样例1举例子,刚开始输入进栈的时候是(2,1)
                之后是输入1,然后2大于1,所以计算下面积,现在的最大面积是2,之后(1,2)进栈
                (2,1)已经出栈了,之后再输入4,比栈顶元素高度大所以进栈(4,1),再输入5,5比栈顶
                元素大,所以入栈为(5,1)再输入一个1,这个时候比栈顶元素小,所以要计算一下以栈顶
                元素的高度为高的矩形面积,宽度以它自身带的宽度,为5所以现在最大面积是5,这个时候(5,1)
                出栈,而现在继续比较(4,1)这个时候4大于1,所以宽度变成2了,高度以栈顶元素的高度,最
                大面积是8了,这个时候是(1,3)入栈了,表示前面有两个高度比他高的了,在下面计算面积的
                时候也就可以计算了。*/
            {
                H=a.top().first;
                W=a.top().second;
                a.pop();
                width=width+W;
                sum=max(sum,H*width);
            }
            a.push(make_pair(height,width+1));
        }
        W=0;
        while(!a.empty())/*到了这里,栈里面矩形的高度就是从栈顶到栈底
            是逐渐减小的了所以宽度往后可以直接进行相加在样例1中就是计算了(3,2)
            还计算了(1,3)这个时候宽度为5了就是2+3*/
        {
            sum=max(sum,a.top().first*(W+a.top().second));
            W+=a.top().second;
            a.pop();
        }
        printf("%lld\n",sum);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值