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 ...
随机推荐
- FragmentTransaction add 和 replace 区别 转
使用 FragmentTransaction 的时候,它提供了这样两个方法,一个 add , 一个 replace . add 和 replace 影响的只是界面,而控制回退的,是事务. public ...
- 创建Django的App
一. 新建1个App,命令:python manage.py startapp lib 1. 打开终端 2. 新建 3. 把业务代码放到每一个APP里面就更专业了. 修改urls里面的代码如下: 运行 ...
- JAVA中的堆、栈等内存分析
在 JAVA 中,有六个不同的地方可以存储数据 1. 寄存器( register ) 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- hive1.1.0建立外部表关联HDFS文件
0. 说明 已经安装好Hadoop和hive环境,hive把元数据存储在mysql数据库.这里仅讨论外部表和HDFS的关联,并且删掉外部表之后,对HDFS上的文件没有影响. 1. 在HDFS创建分区, ...
- 【loj2064】找相同字符
Portal --> loj2064 Solution 这里是用后缀数组做的版本!(晚点再用Sam写一遍qwq) 首先一个字符串的子串其实就是这个字符串某个后缀的前缀,所以我们有一个十分简单 ...
- Git入门指南
git学习资源: Pro Git(中文版) Learn Git in your browser for free with Try Git. Git常用命令 Reference 常用 Git 命令清单 ...
- Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) A 水 B stl C stl D 暴力 E 树状数组
A. Unimodal Array time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- 51nod 1684 子集价值
lyk最近在研究位运算. 它发现除了xor,or,and外还有很多运算. 它新定义了一种运算符“#”. 具体地,可以由4个参数来表示. ai,j表示 i#j. 其中i,j与a的值均∈[0,1]. 当然 ...
- STL源码分析-vector
http://note.youdao.com/noteshare?id=55dc651a7489f1413b3a3169401dcf94
- poj 1696 (计算几何基础)
poj 1696 Space Ant 链接:http://poj.org/problem?id=1696 题意:在坐标轴上,给定n个点的 id 以及点的坐标(xi, yi),让你以最底端点开始,从右依 ...