【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 }