HDU - 4938 Seeing People 二分查找
题意:给出两种人,第一种人初始位置为(pi,0),出发时间为ti,速度[矢量]为(0,vi),视野范围为wi,也就是说当它在(xi,yi)时,能看见(xi,yi)->(xi+wi,yi)这条水平线段上的人【闭区间】
第二种人,初始位置为(0,pi),出发时间为ti,速度为(vi,0),视野范围为wi,当它在(xi,yi),能看见(xi,yi)->(xi,yi+wi)这段垂直线段上人的【闭区间】
现在问,每个人最后能看到多少个不同的人
样例:第一个人和第二个人在第2s时在(1,2)相遇,所以看到的人数分别是1
(1<=n,v1,v2<=10^5)(T<=10)(1<=ai<=2, 1<=ti,pi,wi<=10^5)
题解:
第一种人新坐标\((pi,-v1*ti)\)
第二种人新坐标\((-v2*tj,pj)\)
对于每个第一种人i找有多少第二种人j
第二种人满足的条件为他到x=pi和x=pi+wi的时间为\((pi+v2*tj)/v2\)和\((pi+wi+v2*tj)/v2\)
第一种人到达y=pj的时间为\((pj+v1*ti)/v1\)
所以相遇不等式为\((pi+v2*tj)/v2<=(pj+v1*ti)/v1<=(pi+wi+v2*tj)/v2\)
转化一下中间剩下\(pj-v1*tj\)
得\(v1*pi/v2-v1*ti<=pj-v1*tj<=v1*(pi+wi)/v2-v1*ti\)
预处理第二种人的数组\(pj-v1*tj\)
在这个数组中二分一下左端点和右端点看有多少j满足条件
PS:有个小坑,因为推出来的式子中有除法,用整型向下取整的时候可能会有精度问题,我换成了double才过的
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int T;
typedef long long ll;
int n,n1,n2,t[2][N],p[2][N],w[2][N],id[2][N],ans[N];
double v1,v2;
vector<ll> v;
int main()
{
scanf("%d",&T);
int cas=0;
while(T--)
{
n1=n2=0;
scanf("%d%lf%lf",&n,&v1,&v2);
for(int i=1;i<=n;i++)
{
int a,x,y,z;scanf("%d%d%d%d",&a,&x,&y,&z);
if(a==1) t[0][++n1]=x,p[0][n1]=y,w[0][n1]=z,id[0][n1]=i;
else t[1][++n2]=x,p[1][n2]=y,w[1][n2]=z,id[1][n2]=i;
}
printf("Case #%d:\n",++cas);
v.clear();
for(int i=1;i<=n2;i++)v.push_back(p[1][i]-1ll*v1*t[1][i]);
sort(v.begin(),v.end());
for(int i=1;i<=n1;i++)
{
int l=lower_bound(v.begin(),v.end(),1ll*(v1*p[0][i]/v2)-1ll*(v1*t[0][i]))-v.begin();
int r=upper_bound(v.begin(),v.end(),1ll*(v1*(p[0][i]+w[0][i])/v2)-1ll*(v1*t[0][i]))-v.begin()-1;//cout<<v1*(p[0][i]+w[0][i])/v2-v1*t[0][i]<<endl;
ans[id[0][i]]=r-l+1;
}
v.clear();
for(int i=1;i<=n1;i++)v.push_back(p[0][i]-1ll*v2*t[0][i]);
sort(v.begin(),v.end());
for(int i=1;i<=n2;i++)
{
int l=lower_bound(v.begin(),v.end(),1ll*(v2*p[1][i]/v1)-1ll*(v2*t[1][i]))-v.begin();
int r=upper_bound(v.begin(),v.end(),1ll*(v2*(p[1][i]+w[1][i])/v1)-1ll*(v2*t[1][i]))-v.begin()-1;
ans[id[1][i]]=r-l+1;
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
memset(ans,0,sizeof(ans));
memset(t,0,sizeof(t));
memset(w,0,sizeof(w));
memset(p,0,sizeof(p));
memset(id,0,sizeof(id));
}
return 0;
}

浙公网安备 33010602011771号