【HDU5992】Finding Hotels 【KD树】

题意

 给出n个酒店的坐标和价格,然后m个查询,每个查询给出一个人的坐标和能承受的最大价格,然后找出在他价格承受范围以内,距离他最近的宾馆,如果有多个,那么输出第一个

分析

  kd树的模板题

  

  1     #include <cstdio>
  2     #include <cstring>
  3     #include <algorithm>
  4     #include <iostream>
  5     #include <cmath>
  6     
  7     using namespace std;
  8     const int maxn=200000+100;
  9     const int INF=2147000000;
 10     
 11     typedef long long LL;
 12     inline int read(){
 13         int x(0),f(1);
 14         char ch=getchar();
 15         while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
 16         while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
 17         return x*f;
 18     }
 19     LL ANS;
 20     struct kdNode{
 21         int x[3];
 22         int div;
 23         int id;
 24         bool lef;
 25     }ans,p[maxn],q;
 26     int cmpNo;
 27     bool cmp(kdNode a,kdNode b){
 28         return a.x[cmpNo]<b.x[cmpNo];
 29     }
 30     
 31     inline LL dis(kdNode a,kdNode b){
 32         LL res=(LL)(a.x[0]-b.x[0])*(a.x[0]-b.x[0])+(LL)(a.x[1]-b.x[1])*(a.x[1]-b.x[1]);
 33         return res;
 34     }
 35     void buildKD(int l,int r,kdNode* p,int d){
 36         if(l>r)return;
 37         int m=(l+r)/2;
 38         cmpNo=d;
 39         nth_element(p+l,p+m,p+r+1,cmp);
 40         p[m].div=d;
 41      //    printf("%d %d %lld %lld %lld\n",l,r,p[m].x[0],p[m].x[1],p[m].x[2]);
 42         if(l==r){
 43             p[m].lef=1;
 44             return;
 45         }
 46         buildKD(l,m-1,p,(d+1)%2);
 47         buildKD(m+1,r,p,(d+1)%2);
 48     }
 49     void findkd(int l,int r,kdNode &tar,kdNode *p){
 50         if(l>r)return ;
 51         int m=(l+r)/2;
 52         LL d=dis(p[m],tar);
 53         if(p[m].lef){
 54             if(p[m].x[2]<=tar.x[2]){
 55                 if(ANS>d||(ANS==d&&ans.id>p[m].id)){
 56                     ANS=d;
 57                     ans.id=p[m].id;
 58                     for(int i=0;i<=2;i++)
 59                         ans.x[i]=p[m].x[i];
 60                 }
 61             }
 62             return;
 63         }
 64         int t=tar.x[p[m].div]-p[m].x[p[m].div];
 65         if(t>0){
 66             findkd(m+1,r,tar,p);
 67             if(p[m].x[2]<=tar.x[2]){
 68                 if(ANS>d||(ANS==d&&p[m].id<ans.id)){
 69                     ANS=d;
 70                     for(int j=0;j<=2;j++)
 71                         ans.x[j]=p[m].x[j];
 72                     ans.id=p[m].id;
 73                 }
 74             }
 75             if(ANS>t)
 76                 findkd(l,m-1,tar,p);
 77         }else{
 78             findkd(l,m-1,tar,p);
 79             if(p[m].x[2]<=tar.x[2]){
 80                 if(ANS>d||(ANS==d&&p[m].id<ans.id)){
 81                     ANS=d;
 82                     for(int j=0;j<=2;j++)
 83                         ans.x[j]=p[m].x[j];
 84                     ans.id=p[m].id;
 85                 }
 86             }
 87             if(ANS>-t)
 88                 findkd(m+1,r,tar,p);
 89         }
 90     }
 91     
 92     
 93     int T,n,m;
 94     int main(){
 95         T=read();
 96         for(int kas=1;kas<=T;kas++){
 97           //  scanf("%d%d",&n,&m);
 98             n=read(),m=read();
 99             for(int i=0;i<n;i++){
100                 //scanf("%d%d%d",&p[i].x[0],&p[i].x[1],&p[i].x[2]);
101                 p[i].x[0]=read();p[i].x[1]=read();p[i].x[2]=read();
102                 p[i].lef=0;
103                 p[i].id=i;
104               //  printf("%lld %lld %lld ",p[i].x[0],p[i].x[1],p[i].x[2]);
105             }
106             buildKD(0,n-1,p,1);
107             for(int i=1;i<=m;i++){
108                 ANS=INF;
109                 //scanf("%d%d%d",&q.x[0],&q.x[1],&q.x[2]);
110                 q.x[0]=read();q.x[1]=read();q.x[2]=read();
111                 findkd(0,n-1,q,p);
112                 printf("%d %d %d\n",ans.x[0],ans.x[1],ans.x[2]);
113             }
114         }
115     return 0;
116     }
View Code

 

posted @ 2018-11-02 09:21  蒟蒻LQL  阅读(237)  评论(0编辑  收藏  举报