靠跌成狗了==
第三题我依着良心挖了5次==
KyleYoung开黑直接卡黄了==
而我,掉回蓝民。
讲一下题目。
只A了第三题。
拍照
Description
小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左航行,有的船只向右航行。小明希望拍下这一美丽的风景,并且把尽可能多的船只都完整地拍到一张照片中。
小明位于河的边上,并且可以在河边的任意位置进行拍照,照相机的视野恰好为90度角,只能以垂直于河边的方向进行拍照。河上的船只全都可看作是平行于河边的一条线段,跟河边的距离各不相同,有的正在向左移动,有的正在向右移动,但移动速度恰好都是一样的。小明可以等待恰当的时间让尽量多的船只都走进照相机的视野里,你不需要考虑船只之间会互相遮挡视野的情况。
Solution
这题蛮神==
首先把想两边开的分开
记录每个:
视野1可以看到的向左边开的
视野2可以看到的向右边开的
然后有时候视野1和视野2会重合。
记录一个最大值就好了
暴力判会T,而且内存扛不住。
所以离散一发。
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
const int M=2e4+5e3;
struct node{int x,y;}S[2][M];
int _,txt,cnt[2],sum[M],res[2][M],B[M];
int pos[2][M];
inline void Max(int &a,int b){if(a<b)a=b;}
inline void Min(int &a,int b){if(a>b)a=b;}
inline void gao(){
int n;cin>>n;
memset(sum,0,sizeof(sum));
memset(res,0,sizeof(res));
memset(pos,0,sizeof(pos));
cnt[0]=cnt[1]=0;
//Init
int t=0;
for(int i=1,x,y,z,d;i<=n;++i){
scanf("%d %d %d %d",&x,&y,&z,&d);
if(y-x>z<<1)continue;
if(d==-1)S[1][cnt[1]++]=(node){x+z,y-z};
else S[0][cnt[0]++]=(node){x+z,y-z};
B[t++]=x+z,B[t++]=y-z;
}
//要找的是x-z=>i&&r-z<=i的
sort(B,B+t);
int s=unique(B,B+t)-B;
for(int i=0;i<cnt[0];++i){
S[0][i].x=lower_bound(B,B+s,S[0][i].x)-B;
S[0][i].y=lower_bound(B,B+s,S[0][i].y)-B;
}
for(int i=0;i<cnt[1];++i){
S[1][i].x=lower_bound(B,B+s,S[1][i].x)-B;
S[1][i].y=lower_bound(B,B+s,S[1][i].y)-B;
}
for(int i=0;i<cnt[0];++i)
pos[0][S[0][i].y]++,pos[0][S[0][i].x+1]--;
for(int i=0;i<cnt[1];++i)
pos[1][S[1][i].y]++,pos[1][S[1][i].x+1]--;
int sum1=0,sum2=0;
for(int i=0;i<s;++i){
sum1+=pos[0][i];
res[0][i]=sum1;
sum2+=pos[1][i];
res[1][i]=sum2;
}
sum[0]=res[0][0];
for(int i=1;i<s;++i)
sum[i]=max(sum[i-1],res[0][i]);
int ans=0;sum1=0;
for(int i=s-1;~i;--i){
Max(sum1,res[1][i]);
Max(ans,sum[i]+sum1);
}
printf("Case #%d:\n",++txt);
printf("%d\n",ans);
}
int main(){
for(cin>>_;_--;)gao();
}