Hrbust 2151 变形金刚【思维+前缀和】

本文介绍了一种算法问题,即给定一系列建筑物的宽度和高度,如何计算特殊攻击技能能够一次性摧毁的最大矩形区域面积。文章提供了问题描述、输入输出样例及AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

变形金刚
Time Limit: 3000 MSMemory Limit: 32768 K
Total Submit: 36(13 users)Total Accepted: 12(11 users)Rating: Special Judge: No
Description

新一轮变形金刚来袭,这次霸天虎的头领叫做吊炸天。吊炸天有一个酷炫的攻击技能,能够横向摧毁一个矩形区域内的高楼大厦。但是有个弱点,这个矩形区域必须充满建筑物(不能有空白)。现在吊炸天面对一座城市,假设建筑物都是紧密挨着的(没有缝隙),现在按照顺序给你一些建筑物的宽和高(二维)。 这样的话...吊炸天一次性能摧毁的最大建筑面积是多少?(不考虑区域外造成的损坏)

Input
 

多组测试数据:

每组数据的第一行是一个整数n,表示建筑物的数目;

接下来的n行,每行有两个整数 w,h,分别表示对应建筑物的宽和高。

(1<= T <= 50, 1 <= n <= 50000,0<=总面积<=10^9)

如果n等于0 则结束。

Output
     对于每组数据,输出能一次性摧毁的最大面积。
Sample Input

2

3 4

1 3

3

3 4

1 2

3 4

0

Sample Output

12

14

Source
2014暑假集训练习赛(8月6日)

思路:


我们O(n)枚举一列作为起点,然后向两边贪心找最远能够和这一列组成矩形的位子。左边设定为L【i】,右边设定为R【i】.

那么我们再维护一个关于行长度的前缀和Sum【i】.那么我们维护出来的解就是Sum【R【i】】-Sum【L【i】-1】*H【i】;


那么问题就在于如何寻找L【i】和R【i】.

如果我们暴力去找的话,时间复杂度是O(n^2)很大,所以我们可以将L【i】相关信息存储成一种链式的结构,我们大致可以做到尽可能的O(1)查询。

具体实现细节参考代码即可,不难理解。


Ac代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int w[50005];
int h[50005];
int L[50005];
int R[50005];
int Sum[50005];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==0)break;
        memset(w,0,sizeof(w));
        memset(h,0,sizeof(h));
        memset(L,0,sizeof(L));
        memset(R,0,sizeof(R));
        memset(Sum,0,sizeof(Sum));
        int output=0;
        for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&h[i]);
        for(int i=1;i<=n;i++)L[i]=R[i]=i,Sum[i]=Sum[i-1]+w[i];
        for(int i=1;i<=n;i++)
        {
            int now=i;
            while(L[now]-1>=1&&h[i]<=h[now-1])now=L[now-1];
            L[i]=now;
            now=i;
            while(R[now]+1<=n&&h[i]<=h[now+1])now=R[now+1];
            R[i]=now;
            int row=Sum[R[i]]-Sum[L[i]-1];
            int col=h[i];
            output=max(output,row*col);
        }
        printf("%d\n",output);

    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值