您的位置:首页 > 其它

HDU 5714 拍照 前缀和

2016-06-01 08:36 337 查看

拍照

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=5714

Description

小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行。小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中。

小明位于河的边上,并且可以在河边的任意位置进行拍照,照相机的视野恰好为90度角,只能以垂直于河边的方向进行拍照。河上的船只全都可看作是平行于河边的一条线段,跟河边的距离各不相同,有的正在向左移动,有的正在向右移动,但移动速度恰好都是一样的。小明可以等待恰当的时间让尽量多的船只都走进照相机的视野里,你不需要考虑船只之间会互相遮挡视野的情况。



Input

第一行为T,表示输入数据组数。

下面T组数据,对于每组数据:

第一行是一个数n(1≤n≤104),表示船只的数量。

接下来n行,每行四个整数

x,y,z,d(−106≤xl,r是向左走的船坐标,l是向右走的船的坐标

那么肯定在某一时刻,这俩坐标是会重叠的,所以只要记录一个前缀最大值,然后莽一波就好了

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
map<int,int> H;
int l[maxn],r[maxn],x[maxn],y[maxn],z[maxn],d[maxn];
vector<int>V;
int tot,c[maxn],n;
void init()
{
tot=0;
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
H.clear();V.clear();
}
void solve(int cas)
{
init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&x[i],&y[i],&z[i],&d[i]);
V.push_back(y[i]-z[i]),V.push_back(x[i]+z[i]+1);
}
sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());
for(int i=0;i<V.size();i++)
H[V[i]]=i+1;
for(int i=1;i<=n;i++)
{
if(y[i]-z[i]<=x[i]+z[i])
{
int x1=H[y[i]-z[i]],x2=H[x[i]+z[i]+1];
if(d[i]==1)l[x1]++,l[x2]--;
else r[x1]++,r[x2]--;
}
}
int Max = 0,Ans = 0;
for(int i=1;i<=V.size();i++)
{
l[i]+=l[i-1],r[i]+=r[i-1];
Max=max(Max,l[i]);
Ans=max(Ans,Max+r[i]);
}
printf("Case #%d:\n%d\n",cas,Ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
solve(i);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: