题目意思大致是:给出N个点,然后给出方向向量,然后N个点沿着方向向量引出射线,在m个点(敌人),凡是被射线射到的要死,问最后死多少人。。 n,m都是(0,10000]的。
显然,时间复杂度很明显,不是O(n)就是O(nlog(n) ),我做的是O(nlog(n) )复杂度的,首先我们想到的是每一个射线的起点与X * Y这个平面上延着向量的方向或反方向有个交点(特殊情况,如方向向量平行x * y的话 我们可以通过反转避免); 然后我们用O(n)的复杂度处理了起点,然后对所有在X上的映射点进行排下序,然后O(m)枚举每个敌人,每个敌人与X * Y这个平面也有个交点,我们只要在刚才的交点集找出第一个比当前交点大的点的位置pos,然后根据方向向量在Z轴的方向判断。若z大于0的,pos要-1;小于则不变。然后在判断pos这个点的隐射点是否与我枚举这个敌人在X * Y这个平面的交点相同。 至于为什么pos根据z轴的正负而变化,主要是因为是射线,有可能隐射点是同一个,敌人在射线的反方向上。这种情况敌人是不死的!
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <stdlib.h>
using namespace std;
#define eps 1e-6
const int N=10010;
struct node
{
double x,y,z;
};
node p[N];
node dia[N];
node src[N];
int n,m;
bool cmp(const node &a,const node &b)
{
if(fabs(a.x-b.x)<eps)
{
if(fabs(a.y-b.y)<eps)
return a.z<b.z;
return a.y<b.y;
}
return a.x<b.x;
}
node touying(double x,double y,double z,node dir)
{
node res;
res.x=x-z*dir.x/dir.z;
res.y=y-z*dir.y/dir.z;
res.z=z;
return res;
}
void solve(int cas)
{
int i,j,ans=0;
int flag;
node now,dir;
for(i=1;i<=m;i++)
scanf("%lf%lf%lf",&dia[i].x,&dia[i].y,&dia[i].z);
for(i=1;i<=n;i++)
scanf("%lf%lf%lf",&src[i].x,&src[i].y,&src[i].z);
scanf("%lf%lf%lf",&dir.x,&dir.y,&dir.z);
printf("Case %d: ",cas);
if (dir.z==0)
{
if(dir.y!=0)
{
for(i=1;i<=n;i++)
swap(src[i].y,src[i].z);
for(i=1;i<=m;i++)
swap(dia[i].y,dia[i].z);
swap(dir.y,dir.z);
}
else
{
for(i=1;i<=n;i++)
swap(src[i].x,src[i].z);
for(i=1;i<=m;i++)
swap(dia[i].x,dia[i].z);
swap(dir.x,dir.z);
}
}
if(dir.z>0) flag=1;
else flag = 0;
for(i=1;i<=n;i++)
{
p[i] = touying(src[i].x,src[i].y,src[i].z,dir);
}
sort(p+1,p+1+n,cmp);
p[n+1].x=p[n+1].y=p[n+1].z=100000000;
p[0].x=p[1].x-1;
for(i=1;i<=m;i++)
{
now = touying(dia[i].x,dia[i].y,dia[i].z,dir);
now.z+=eps;
int pos=lower_bound(p+1,p+1+n,now,cmp) - p;
if(flag)
{
if(pos==1)
continue;
pos--;
}
if(pos!=n+1)
{
// printf("%lf/n",(*it).z);
if(fabs(p[pos].x-now.x)<eps && fabs(p[pos].y-now.y)<eps)
ans++;
}
}
printf("%d/n",ans);
}
int main()
{
int i,j;
int T,cas=1;
scanf("%d",&T);
while( T--)
{
scanf("%d%d",&m,&n);
solve(cas);
cas ++;
}
return 0;
}