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 ...
随机推荐
- bzoj2818 Gcd(欧拉函数)
Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...
- Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...
- CF530D sum in the tree
我是题面.原题地址 很简单的一道贪心题 首先,先想想怎么判断是否合法 题目中说,a是自然数,那么子节点的s明显是不能比父节点大的,如果比父节点大,不合法! 所有深度为偶数的点的s被删除了,也只有深度为 ...
- 【BZOJ2727】双十字(动态规划,树状数组)
[BZOJ2727]双十字(动态规划,树状数组) 题面 BZOJ 洛谷 题解 我们去年暑假的时候考试考过. 我当时写了个大暴力混了\(70\)分.... 大暴力是这么写的: 预处理每个位置向左右/上/ ...
- 洛谷 U14475 部落冲突 【比赛】 【树链剖分 + 线段树】
题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...
- struts2(s2-052)远程命令执行漏洞复现
漏洞描述: 2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为C ...
- bzoj3192: [JLOI2013]删除物品(树状数组)
既然要从一个堆的堆顶按顺序拿出来放到第二个堆的堆顶,那么我们就可以把两个堆顶怼在一起,这样从一个堆拿到另一个堆只需要移动指针就好了. 换句话说,把1~n倒着,n+1到n+m正着,用一个指针把两个序列分 ...
- STL源码分析-rotate
http://note.youdao.com/noteshare?id=4ba8ff81aa96373ba11f1b82597ec73a
- '0','\0',NULL,EOF的区别
要看是不是一个东西,打印一下即可 printf("%d %d %d %d\n",'0','\0',NULL,EOF); 输出: 48 0 0 -1 结论: '\0'与NULL 都是 ...
- 解决html设置height:100%无效的问题
通常我们需要让自己的网页内容能够更好的适配各种屏幕大小,会采用height:100%,但是我们发现问题出来了,height:100%无效,其实解决办法很简单 解决:你只需要在css处添加上html, ...