FZU 网赛最后K题 Three kingdoms(有点卡常数的)

来源:互联网 发布:js中国地图插件 编辑:程序博客网 时间:2024/06/05 22:50

题目意思大致是:给出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;

}

 

原创粉丝点击