【hdu4347】The Closest M Points 【KD树模板】

题意

一个k维空间,给出n个点的坐标,给出t个询问,每个询问给出一个点的坐标和一个m。对于每个询问找出跟这个点最接近的m个点

分析

kd树的模板题。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <queue>
  6
  7 using namespace std;
  8 typedef long long LL;
  9 const int maxn=50080;
 10 const int K=5;
 11 int num,nownum,m;
 12 LL ans;
 13 struct kdNode{
 14     LL x[K];
 15     int div;
 16     bool lef;
 17 }Ans[12];
 18 struct Node{
 19     kdNode a;
 20     LL dis;
 21     bool operator <(const Node &a)const{
 22         return dis<a.dis;
 23     }
 24     Node(){}
 25     Node(kdNode &tmp,LL d){
 26         a=tmp;
 27         dis=d;
 28     }
 29 };
 30 int cmpNo;
 31 bool cmp(kdNode a,kdNode b){
 32     return a.x[cmpNo]<b.x[cmpNo];
 33 }
 34 inline LL max(LL a,LL b){//why?
 35     return a>b?a:b;
 36 }
 37 kdNode p[maxn],q;
 38 LL dis(kdNode a,kdNode b,int k){
 39     LL res=0;
 40     for(int i=0;i<k;i++){
 41         res+=(a.x[i]-b.x[i])*(a.x[i]-b.x[i]);
 42     }
 43     return res;
 44 }
 45 priority_queue<Node>qq;
 46 void buildKD(int l,int r,kdNode* p,int d,int k){
 47     if(l>r)return ;
 48     int m=(l+r)/2;
 49     cmpNo=d;
 50     nth_element(p+l,p+m,p+r+1,cmp);
 51     p[m].div=d;
 52     if(l==r){
 53         p[m].lef=1;
 54         return ;
 55     }
 56     buildKD(l,m-1,p,(d+1)%k,k);
 57     buildKD(m+1,r,p,(d+1)%k,k);
 58 }
 59 void findkd(int l,int r,kdNode& tar,kdNode* p,int k){
 60     if(l>r)return;
 61     int m=(l+r)/2;
 62     LL d=dis(p[m],tar,k);
 63     if(p[m].lef){
 64         if(nownum<num){
 65             nownum++;
 66             ans=max(ans,d);
 67             qq.push(Node(p[m],d));
 68         }
 69         else if(ans>d){
 70             qq.pop();
 71             qq.push(Node(p[m],d));
 72             ans=qq.top().dis;
 73         }
 74         return;
 75     }
 76     LL t=tar.x[p[m].div]-p[m].x[p[m].div];
 77     if(t>0){
 78         findkd(m+1,r,tar,p,k);
 79         if(nownum<num){
 80             qq.push(Node(p[m],d));
 81             nownum++;
 82             ans=qq.top().dis;
 83             findkd(l,m-1,tar,p,k);
 84         }else{
 85             if(ans>d){
 86                 qq.pop();
 87                 qq.push(Node(p[m],d));
 88                 ans=qq.top().dis;
 89             }
 90             if(ans>t*t)
 91                 findkd(l,m-1,tar,p,k);
 92         }
 93     }else{
 94         findkd(l,m-1,tar,p,k);
 95         if(nownum<num){
 96             qq.push(Node(p[m],d));
 97             nownum++;
 98             ans=qq.top().dis;
 99             findkd(m+1,r,tar,p,k);
100         }else{
101             if(ans>d){
102                 qq.pop();
103                 qq.push(Node(p[m],d));
104                 ans=qq.top().dis;
105             }
106             if(ans>t*t){
107                 findkd(m+1,r,tar,p,k);
108             }
109         }
110     }
111 }
112
113 int n,k;
114 int main(){
115     while(scanf("%d%d",&n,&k)==2){
116         for(int i=0;i<n;i++){
117             for(int j=0;j<k;j++){
118                 scanf("%lld",&p[i].x[j]);
119             }
120             p[i].lef=0;
121         }
122         buildKD(0,n-1,p,k-1,k);
123         int t;
124         scanf("%d",&t);
125         for(int i=1;i<=t;i++){
126             ans=-1;
127             nownum=0;
128             for(int j=0;j<k;j++){
129                 scanf("%lld",&q.x[j]);
130             }
131             while(!qq.empty())qq.pop();
132             scanf("%d",&num);
133             findkd(0,n-1,q,p,k);
134             for(int j=1;j<=num;j++){
135                 Ans[j]=qq.top().a;
136                 qq.pop();
137             }
138             printf("the closest %d points are:\n",num);
139             for(int j=num;j>=1;j--){
140                 for(int kk=0;kk<k;kk++){
141                     if(kk==0)
142                         printf("%lld",Ans[j].x[kk]);
143                     else
144                         printf(" %lld",Ans[j].x[kk]);
145                 }
146                 printf("\n");
147             }
148         }
149     }
150 return 0;
151 }

原文地址:https://www.cnblogs.com/LQLlulu/p/9894346.html

时间: 2024-11-08 05:46:03

【hdu4347】The Closest M Points 【KD树模板】的相关文章

bzoj 3053 HDU 4347 : The Closest M Points kd树

bzoj 3053 HDU 4347 : The Closest M Points  kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差较大的维度分开(建树常数大)或者每一位轮换分割(询问常数大),后者更快也更好些,以后就果断写第二种了. #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using

hdu 4347 The Closest M Points (kd树)

hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说,上代码 . 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <s

The Closest M Points//kd树+优先队列

题目 The Closest M Points Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Others) Total Submission(s): 7570 Accepted Submission(s): 2378 Problem Description The course of Software Design and Development Practice is objectionab

【BZOJ3053】The Closest M Points KDtree 好模板一只【数组版!!!】

题解:多维的估价跟二维一样,每一维的贡献跟二维的'x'.'y'完全相同. 真不明白不会的是怎么想的,有区别么?!! 细节: 妈蛋的多组数据!调了好久啊. 然后行末还不能有空格,否则PE 除去这些,我是1A.. 可惜没有"除去"这一说. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 50100 #define K

HDU 5992 Finding Hotels(KD树)题解

题意:n家旅店,每个旅店都有坐标x,y,每晚价钱z,m个客人,坐标x,y,钱c,问你每个客人最近且能住进去(非花最少钱)的旅店,一样近的选排名靠前的. 思路:KD树模板题 代码: #include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<c

数据结构(KD树):HDU 4347 The Closest M Points

The Closest M Points Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Others)Total Submission(s): 3285    Accepted Submission(s): 1201 Problem Description The course of Software Design and Development Practice is objection

HDU 4347 - The Closest M Points - [KDTree模板题]

本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4347 Problem Description The course of Software Design and Development Practice is objectionable. ZLC is facing a serious problem

BZOJ3053 The Closest M Points

裸的KD-tree,还是在估计要不要进入子树的时候判断一下就好了,剩下都一样 判断的方法就是看现在答案个数是否小于k,和答案是否会经过分割线. 1 /************************************************************** 2 Problem: 3053 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:2164 ms 7 Memory:3572 kb 8 ************

K-D树问题 HDU 4347

K-D树可以看看这个博客写的真心不错!这里存个版 http://blog.csdn.net/zhjchengfeng5/article/details/7855241 HDU 4349 #include <map> //KD树学习http://blog.csdn.net/zhjchengfeng5/article/details/7855241 #include <set> #include <list> #include <cmath> #include