hdu 4347 The Closest M Points (kd树)
版权声明:本文为博主原创文章,未经博主允许不得转载。
题意:
求k维空间中离所给点最近的m个点,并按顺序输出 。
解法:
kd树模板题 。
不懂kd树的可以先看看这个 。
不多说,上代码 。
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cmath>
- #include <cstring>
- #include <queue>
- #include <set>
- #include <vector>
- #include <map>
- #define ll long long
- using namespace std;
- const int N=;
- const int K=;
- int n,m;
- struct point{
- int a[K];
- int div; // 按哪个维度划分
- bool lef; // 是否是叶子节点
- ll dis; // 离询问点的距离。注意这个在读入建树时不会用到,在进入队列时才用到
- void print(){
- printf("%d",a[]);
- for (int i=;i<m;i++)
- printf(" %d",a[i]);
- puts("");
- }
- bool operator < (const point &t) const{
- return dis<t.dis;
- }
- point(){}
- point(point &t,ll d){
- for (int i=;i<m;i++) a[i]=t.a[i];
- dis=d;
- }
- }p[N],tar;
- int cmp_NO;
- inline bool cmp(point x,point y){
- return x.a[cmp_NO]<y.a[cmp_NO];
- }
- inline ll dis(point x,point y){
- ll ret=;
- for (int i=;i<m;i++)
- ret+=(x.a[i]-y.a[i])*(x.a[i]-y.a[i]);
- return ret;
- }
- inline void bulid_kdt(int L,int R,int d){
- if (L>R) return;
- int mid=(L+R)>>;
- cmp_NO=d;
- nth_element(p+L,p+mid,p+R+,cmp);
- p[mid].div=d;
- if (L==R){
- p[L].lef=true;
- return;
- }
- bulid_kdt(L,mid-,(d+)%m);
- bulid_kdt(mid+,R,(d+)%m);
- }
- priority_queue<point> que;
- int num,nownum;
- ll ans;
- inline void find_kd(int L,int R){
- if (L>R) return;
- int mid=(L+R)>>;
- ll d=dis(p[mid],tar);
- if (p[mid].lef){
- if (nownum<num){
- nownum++;
- que.push(point(p[mid],d));
- ans=max(ans,d);
- }
- else if (ans>d){
- que.pop();
- que.push(point(p[mid],d));
- ans=que.top().dis;
- }
- return;
- }
- int t=tar.a[p[mid].div]-p[mid].a[p[mid].div];
- if (t>){
- find_kd(mid+,R);
- if (nownum<num){
- nownum++;
- que.push(point(p[mid],d));
- ans=max(ans,d);
- find_kd(L,mid-);
- }
- else {
- if (ans>d){
- que.pop();
- que.push(point(p[mid],d));
- ans=que.top().dis;
- }
- if (ans>t*t)
- find_kd(L,mid-);
- }
- }
- else {
- find_kd(L,mid-);
- if (nownum<num){
- nownum++;
- que.push(point(p[mid],d));
- ans=max(ans,d);
- find_kd(mid+,R);
- }
- else{
- if (ans>d){
- que.pop();
- que.push(point(p[mid],d));
- ans=que.top().dis;
- }
- if (ans>t*t)
- find_kd(mid+,R);
- }
- }
- }
- inline void put(){
- if (que.empty()) return;
- point pp=que.top();
- que.pop();
- put();
- pp.print();
- }
- int main(){
- while (~scanf("%d%d",&n,&m)){
- for (int i=;i<n;i++){
- for (int j=;j<m;j++)
- scanf("%d",&p[i].a[j]);
- p[i].lef=false;
- }
- bulid_kdt(,n-,); // 这一步相当于将原数组重新排了个序,先访问到的点放在中间
- int q;
- scanf("%d",&q);
- while (q--){
- for (int i=;i<m;i++)
- scanf("%d",&tar.a[i]);
- while (!que.empty()) que.pop();
- scanf("%d",&num);
- nownum=;
- ans=-;
- find_kd(,n-);
- printf("the closest %d points are:\n",num);
- put();
- }
- }
- return ;
- }
hdu 4347 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树的两种建树方式,即按照方差 ...
- hdu 4347 The Closest M Points(KD树)
Problem - 4347 一道KNN的题.直接用kd树加上一个暴力更新就撸过去了.写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天. ...
- 数据结构(KD树):HDU 4347 The Closest M Points
The Closest M Points Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Ot ...
- HDU 4347 - The Closest M Points - [KDTree模板题]
本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn ...
- HDU 4347 The Closest M Points (kdTree)
赤果果的kdTree. 学习传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html 其实就是二叉树的变形 #includ ...
- 【HDOJ】4347 The Closest M Points
居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...
- BZOJ 3053: The Closest M Points(K-D Tree)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1235 Solved: 418[Submit][Status][Discuss] Descripti ...
- [hdu4347]The Closest M Points(线段树形式kd-tree)
解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...
- BZOJ3053:The Closest M Points(K-D Teee)
Description The course of Software Design and Development Practice is objectionable. ZLC is facing a ...
随机推荐
- CGLib动态代理引起的空指针异常
一个同事将公司的开发框架基于最新的Spring.Tomcat.Java版本作了部分修改,拿来开发运行之后,发现一个奇怪的空指针异常. 还原一下当时的场景,代码大概如下,所有的Servlet继承自Bas ...
- VS中碰到的问题
1.调试的时候,语句已经注释掉了,但是在执行的时候还是运行了(或者某些变量值改变后,程序依然用的之前数据). 右键解决方案-->清理,然后重新生成.
- 洛谷 P1560 蜗牛的旅行
明显这是一道搜索题,其他题解写的有点复杂,我有更简便的写法 既然题目说走到不能再走,那我们就干脆一点,一条路走到黑,不到南墙不回头,一下把要走的路都走完,不但效率高,也好写,关键是大大节省了系统栈 一 ...
- 两种方法实现TAB菜单及文件操作
1,自定义属性的方法实现----TAB菜单操作 cursor:pointer; 鼠标的小手 <!DOCTYPE html> <html lang="en"> ...
- [AT2064] [agc005_f] Many Easy Problems
题目链接 AtCoder:https://agc005.contest.atcoder.jp/tasks/agc005_f 洛谷:https://www.luogu.org/problemnew/sh ...
- 小Z的袜子 题解报告【莫队】
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只 ...
- 自动化测试常用断言的使用方法(python)
自动化测试中寻找元素并进行操作,如果在元素好找的情况下,相信大家都可以较熟练地编写用例脚本了,但光进行操作可能还不够,有时候也需要对预期结果进行判断. 这里介绍几个常用断言的使用方法,可以一定程度上帮 ...
- 51nod 1952 栈(单调队列)
用deque实时维护栈的情况. 数加入栈顶部,删掉栈顶部的数,相当于加入一个数,删掉最早出现的数,每次求最大值,这个直接记录一下就好了. 数加入栈底部,删掉栈顶部的数,相当于加入一个数,删掉最晚出现的 ...
- 解题:ZJOI 2006 书架
题面 学习了如何在维护序列的平衡树上查找某个数:按初始的顺序定个权值,然后每次找那个权值的DFS序即可.具体实现就是不停往上跳,然后是父亲的右儿子就加上父亲的左儿子,剩下的就是继续熟悉无旋树堆 #in ...
- 【agc006C】Rabbit Exercise
Portal --> agc006C Solution 啊感觉是好有意思的一道题qwq官方题解里面的说辞也是够皮的哈哈哈..(大概就是说如果你没有意识到那个trick的话这题这辈子都做不出来qw ...