题目

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 objectionable. ZLC is facing a serious problem .There are many points in K-dimensional space .Given a point. ZLC need to find out the closest m points. Euclidean distance is used as the distance metric between two points. The Euclidean distance between points p and q is the length of the line segment connecting them.In Cartesian coordinates, if p = (p1, p2,..., pn) and q = (q1, q2,..., qn) are two points in Euclidean n-space, then the distance from p to q, or from q to p is given by:

Can you help him solve this problem?

Input
In the first line of the text file .there are two non-negative integers n and K. They denote respectively: the number of points, 1 <= n <= 50000, and the number of Dimensions,1 <= K <= 5. In each of the following n lines there is written k integers, representing the coordinates of a point. This followed by a line with one positive integer t, representing the number of queries,1 <= t <=10000.each query contains two lines. The k integers in the first line represent the given point. In the second line, there is one integer m, the number of closest points you should find,1 <= m <=10. The absolute value of all the coordinates will not be more than 10000.
There are multiple test cases. Process to end of file.

Output
For each query, output m+1 lines:
The first line saying :”the closest m points are:” where m is the number of the points.
The following m lines representing m points ,in accordance with the order from near to far
It is guaranteed that the answer can only be formed in one ways. The distances from the given point to all the nearest m+1 points are different. That means input like this:
2 2
1 1
3 3
1
2 2
1
will not exist.

Sample Input

3 2
1 1
1 3
3 4
2
2 3
2
2 3
1

Sample Output

the closest 2 points are:
1 3
3 4
the closest 1 points are:
1 3

思路

先构建kd树,循环地以每个维度作为划分依据来划分数据,顺便标记下边界,便于后面的查找.然后是查找,先找到距离所要查的点的最近的叶节点,然后回溯.此时当队列为空直接放入队列,或当前维度下,当前点到所查点的距离小于队顶元素的距离,也放入队列,这两种情况时都要去搜当前点的另一边的,因为可能存在交集.还有要注意输出格式最后一个不能有空格;因为要多次测试,所以每次开始前要把队列pop空.

代码

#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#define Pow(x) (x) * (x)
using namespace std;const int N = 50000+10;
const int K = 5;int n, k, idx;//n个k维数据,idx是用来索引比较的那一维度struct node
{int feature[K];bool operator < (const node & u) const {return feature[idx] < u.feature[idx];}
};struct node data[N];//存放原始数据
priority_queue<pair<double, node>> Q;
struct node kdtree[4*N];//存放kd树
int flag[4*N];//用来标记边界,便于查找void Build(int l, int r, int p, int depth)
{if (l > r)return;flag[p] = 1;flag[p*2] = flag[p*2+1] = -1;idx = depth % k;int mid = (l + r) / 2;nth_element(data+l, data+mid, data+r+1);//找中间那个来划分数据kdtree[p] = data[mid];Build(l, mid-1, p*2, depth+1);Build(mid+1, r, p*2+1, depth+1);
}void Query(node c, int num, int p, int depth)
{if(flag[p] == -1)//搜到边界,返回return;pair<double, node> cur(0, kdtree[p]);for(int i = 0; i < k; i++){cur.first += Pow(cur.second.feature[i] - c.feature[i]);}   int dim = depth % k;//这里没用全局变量idx是因为搜索时该变量会前后递归调用很多次,全局变量可能会改变,然后导致错误bool fg = 0;//标记是否还要继续搜int x = p*2;int y = p*2+1;if(c.feature[dim] >= kdtree[p].feature[dim])//往接近的地方搜swap(x,y);if(~flag[x])//未到边界Query(c,num,x,depth+1);//搜到底后递归回去if(Q.size() < num)//队列未满时,数据直接放入,但要标记下,因为之后可能会被更新{Q.push(cur);fg = 1;}else//队列已满{if(cur.first < Q.top().first)//若当前点比队顶数据小,则更新队列{Q.pop();Q.push(cur);}if(Pow(c.feature[dim] - kdtree[p].feature[dim]) < Q.top().first)//二维解释:划分直线另一侧的点到这一侧的点A的距离必然大于等于划分直线到A点的距离{fg = 1;}}if(~flag[y] && fg)//搜索当前节点的另一个分支,因为可能有交集Query(c,num,y,depth+1);
}int main()
{int i, j, m, q;while(scanf("%d%d", &n, &k) != EOF){for(i = 0; i < n; i++){for(j = 0; j < k; j++){scanf("%d", &data[i].feature[j]);}}Build(0,n-1,1,0);int t;//查询几次int num;//查询前多少个struct node temp;//存放待查询的数据scanf("%d", &t);for(i = 0; i < t; i++){   for(j = 0; j < k; j++){scanf("%d", &temp.feature[j]);}scanf("%d", &num);while(!Q.empty())//这里要注意Q.pop();Query(temp,num,1,0);struct node ans[20];for(m = 0; !Q.empty(); m++){ans[m] = Q.top().second;Q.pop();}printf("the closest %d points are:\n", num);for(m = num - 1; m >= 0; m--){for(q = 0; q < k; q++){printf("%d%c", ans[m].feature[q], q == k-1 ? '\n' : ' ');//这里要注意最后一个不能有空格}}}}
}

参考
https://blog.csdn.net/javays1/article/details/50369176//原理解释的非常清楚

转载于:https://www.cnblogs.com/w-j-c/p/10064484.html

The Closest M Points//kd树+优先队列相关推荐

  1. The Closest M Points BZOJ 3053

    The Closest M Points [问题描述] 软工学院的课程很讨厌!ZLC同志遇到了一个头疼的问题:在K维空间里面有许多的点,对于某些给定的点,ZLC需要找到和它最近的m个点. (这里的距离 ...

  2. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    原文出自:http://blog.csdn.net/v_JULY_v/article/details/8203674 前言 前两日,在微博上说:"到今天为止,我至少亏欠了3篇文章待写:1.K ...

  3. 【转】从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    最近在看<统计学习方法>,发现这么一篇好文章,与大家分享 转自:http://blog.csdn.net/v_july_v/article/details/8203674?reload 前 ...

  4. 统计学习方法笔记(二)-kd树原理及python实现

    kd树 kd树简介 构造平衡kd树算法原理 kd树代码实现 案例地址 kd树简介 kdkdkd树是一种对kkk维空间中的实例点进行存储以便对其进行快速检索的树形数据结构. kdkdkd树构造方法: 构 ...

  5. 【BZOJ】3053: The Closest M Points(kdtree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!! ...

  6. PCL点云库:Kd树

    Kd树按空间划分生成叶子节点,各个叶子节点里存放点数据,其可以按半径搜索或邻区搜索.PCL中的Kd tree的基础数据结构使用了FLANN以便可以快速的进行邻区搜索.FLANN is a librar ...

  7. java knn kd树_KNN算法之KD树(K-dimension Tree)实现 K近邻查询

    KD树是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的搜索,如范围搜索和最近邻搜索. KD树使用了分治的思想,对比二叉搜索树(BST),KD树解决的是多维空间内的最近点(K近点)问题.( ...

  8. BZOJ 3053 The Closest M Points

    [题目分析] 典型的KD-Tree例题,求k维空间中的最近点对,只需要在判断的过程中加上一个优先队列,就可以了. [代码] #include <cstdio> #include <c ...

  9. open3d中的kd树详解

    文章目录 open3d实现 原理 k-d树是一种点云划分方法,其基本思路是,对方差最差的维度进行二分分割,从而得到两个子集,再对这两个子集进行相同的操作,直到所有子集的元素个数低于设定值. 考虑到大部 ...

  10. Matlab点云处理及可视化第1期—基于KD树的邻域点搜索(柱状邻域、球状邻域及KNN)

    目录 1 概述 2 代码实现 3 可视化验证 数据及完整代码获取方式: 观前提示:本文文字内容请勿直接用于论文写作,否则后果自负. 特别提示:<Matlab点云处理及可视化>系列文章旨在为 ...

最新文章

  1. 中科曙光携手甘肃酒泉,积极构建新型智慧城市
  2. my Lead add Lead test
  3. 你真的了解Java系统启动流程吗?mysql不包含多个字符
  4. java scipt 对象 函数_java script 基本函数
  5. 2019 Java 开发者跳槽指南.pdf (吐血整理)
  6. pytorch tensor数据类型与变换类型
  7. 国庆海报没有灵感,给你设计要点素材!
  8. [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】
  9. Mac无损音乐播放器:Audirvana
  10. java编程思想(注释文档)
  11. 在线教学战“疫”打响,VIPKID背后是阿里云
  12. java程序用户权限管理,java用户管理权限
  13. 基于SSM+VUE游戏账号交易系统
  14. HTML5 codecademy
  15. python爬虫:利用BeautifulSoup爬取链家深圳二手房首页的详细信息
  16. Power BI 学习六:报表中视觉对象元素
  17. Android P Keyguard Scrim快速灭屏亮屏闪亮
  18. 折腾开源WRT的AC无线路由之路-3
  19. 【react-hook】 useCallback
  20. 技术视频下载地址分享

热门文章

  1. Linux编写shell脚本的注意事项
  2. 超级简单:如何列出目录下所有文件的超链接
  3. 批处理添加桌面快捷方式
  4. Delegate示例
  5. 【从C到C++学习笔记】内联成员函数/成员函数重载及缺省参数
  6. 数组中的奇数排在偶数组前面
  7. CASS9.1计算土方量实例
  8. Nginx根据url参数匹配跳转
  9. 实习成长之路:面试官说的MySQL高可用-------主备一致到底是什么?
  10. Python基础语法-05-装饰器