您的位置:首页 > 其它

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

2017-06-20 16:37 323 查看
变形金刚
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);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Hrbust 2151