BZOJ3053:The Closest M Points(K-D Teee)
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:
D(p,q)=D(q,p)=sqrt((q1-p1)^2+(q2-p2)^2+(q3-p3)^2…+(qn-pn)^2
Can you help him solve this problem?
软工学院的课程很讨厌!ZLC同志遇到了一个头疼的问题:在K维空间里面有许多的点,对于某些给定的点,ZLC需要找到和它最近的m个点。
(这里的距离指的是欧几里得距离:D(p, q) = D(q, p) = sqrt((q1 - p1) ^ 2 + (q2 - p2) ^ 2 + (q3 - p3) ^ 2 + ... + (qn - pn) ^ 2)
ZLC要去打Dota,所以就麻烦你帮忙解决一下了……
【Input】
第一行,两个非负整数:点数n(1 <= n <= 50000),和维度数k(1 <= k <= 5)。
接下来的n行,每行k个整数,代表一个点的坐标。
接下来一个正整数:给定的询问数量t(1 <= t <= 10000)
下面2*t行:
第一行,k个整数:给定点的坐标
第二行:查询最近的m个点(1 <= m <= 10)
所有坐标的绝对值不超过10000。
有多组数据!
【Output】
对于每个询问,输出m+1行:
第一行:"the closest m points are:" m为查询中的m
接下来m行每行代表一个点,按照从近到远排序。
保证方案唯一,下面这种情况不会出现:
2 2
1 1
3 3
1
2 2
1
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
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
Solution
还是K-D Tree模板,不过这个是真正的多维KDT,做的时候把原来的0/1扩展到多维就好了
查询m远的时候开个大根堆,当答案小于堆顶的时候就push进去,然后query内部稍微改一下
因为query的时候lans和rans忘了赋初值调了半天emmm……
Code
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<cmath>
- #include<queue>
- #include<algorithm>
- #define N (50000+1000)
- #define INF 1e16
- using namespace std;
- struct P
- {
- long long dis,num;
- bool operator < (const P &a) const {return dis<a.dis;}
- }po;
- long long n,k,D,t,Root,m,ans[N];
- priority_queue<P>q;
- struct Node
- {
- long long Max[],Min[],d[],lson,rson;
- bool operator < (const Node &a) const {return d[D]<a.d[D];}
- }p[N],T;
- struct KDT
- {
- Node Tree[N];
- long long sqr(long long x){return x*x;}
- void Update(long long now)
- {
- for (int i=;i<k; ++i)
- {
- long long ls=Tree[now].lson, rs=Tree[now].rson;
- Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
- if (ls)
- {
- Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
- Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
- }
- if (rs)
- {
- Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
- Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
- }
- }
- }
- long long Build(long long opt,long long l,long long r)
- {
- if (l>r) return ;
- long long mid=(l+r)>>;
- D=opt; nth_element(p+l,p+mid,p+r+);
- Tree[mid]=p[mid];
- Tree[mid].lson=Build((opt+)%k,l,mid-);
- Tree[mid].rson=Build((opt+)%k,mid+,r);
- Update(mid); return mid;
- }
- long long Get_min(long long now)
- {
- long long ans=;
- for (int i=; i<k; ++i)
- {
- if (T.d[i]>Tree[now].Max[i]) ans+=sqr(T.d[i]-Tree[now].Max[i]);
- if (T.d[i]<Tree[now].Min[i]) ans+=sqr(Tree[now].Min[i]-T.d[i]);
- }
- return ans;
- }
- void Query(int now)
- {
- long long ls=Tree[now].lson, rs=Tree[now].rson, lans=INF,rans=INF;
- if (ls) lans=Get_min(ls);
- if (rs) rans=Get_min(rs);
- long long dist=;
- for (int i=; i<k; ++i)
- dist+=sqr(Tree[now].d[i]-T.d[i]);
- po.dis=dist; po.num=now;
- if (dist<q.top().dis)
- q.pop(),q.push(po);
- if (lans<rans)
- {
- if (lans<q.top().dis) Query(ls);
- if (rans<q.top().dis) Query(rs);
- }
- else
- {
- if (rans<q.top().dis) Query(rs);
- if (lans<q.top().dis) Query(ls);
- }
- }
- }KDT;
- int main()
- {
- while (scanf("%lld%lld",&n,&k)!=EOF)
- {
- for (int i=; i<=n;++i)
- for (int j=; j<k; ++j)
- scanf("%lld",&p[i].d[j]);
- Root=KDT.Build(,,n);
- scanf("%lld",&t);
- for (int i=; i<=t; ++i)
- {
- for (int j=; j<k; ++j)
- scanf("%lld",&T.d[j]);
- scanf("%lld",&m);
- for (int i=; i<=m; ++i)
- {
- po.dis=INF; po.num=;
- q.push(po);
- }
- KDT.Query(Root);
- for (int i=; i<=m; ++i)
- ans[i]=q.top().num,q.pop();
- printf("the closest %lld points are:\n",m);
- for (int i=m; i>=; --i)
- {
- for (int j=; j<k; ++j)
- printf("%lld ",p[ans[i]].d[j]);
- printf("\n");
- }
- }
- }
- }
BZOJ3053:The Closest M Points(K-D Teee)的更多相关文章
- 【kd-tree】bzoj3053 The Closest M Points
同p2626.由于K比较小,所以不必用堆. #include<cstdio> #include<cstring> #include<cmath> #include& ...
- BZOJ3053: The Closest M Points
题解: 我们可以事先在堆里放入插入m个inf然后不断的比较当前值与堆首元素的大小,如果小于的话进入. 估计函数也可以随便写写... query的时候貌似不用保留dir... return 0写在 wh ...
- 【BZOJ 3053】The Closest M Points
KDTree模板,在m维空间中找最近的k个点,用的是欧几里德距离. 理解了好久,昨晚始终不明白那些“估价函数”,后来才知道分情况讨论,≤k还是=k,在当前这一维度距离过线还是不过线,过线则要继续搜索另 ...
- BZOJ 3053 The Closest M Points
[题目分析] 典型的KD-Tree例题,求k维空间中的最近点对,只需要在判断的过程中加上一个优先队列,就可以了. [代码] #include <cstdio> #include <c ...
- 【BZOJ】3053: The Closest M Points(kdtree)
http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!! ...
- 【HDOJ】4347 The Closest M Points
居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...
- bzoj 3053 HDU 4347 : The Closest M Points kd树
bzoj 3053 HDU 4347 : The Closest M Points kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...
- 数据结构(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 ...
- poj:4091:The Closest M Points
poj:4091:The Closest M Points 题目 描写叙述 每到饭点,就又到了一日几度的小L纠结去哪吃饭的时候了.由于有太多太多好吃的地方能够去吃,而小L又比較懒不想走太远,所以小L会 ...
随机推荐
- MYSQL分区表详解
分区表对用户来说是一个独立的逻辑表,但是底层是多个物理字表组成的.分区代码实际上是对一组底层表的句柄对象封装.对分区表的请求,都会通过句柄对象转化成储存引擎的接口调用.所以分区对于SQL层来说是一个完 ...
- Ace教你一步一步做Android新闻客户端(五) 优化Listview
今天写存货了 调试一些动画参数花了些时间 ,嘿嘿存货不多了就没法做教程了,今天来教大家优化listview,等下我把代码编辑下 这次代码有些多 所以我把条理给大家理清楚.思路就是把加载图片的权利交给O ...
- [Scala] Pattern Matching(模式匹配)
Scala中的match, 比起以往使用的switch-case有著更強大的功能, 1. 傳統方法 def toYesOrNo(choice: Int): String = choice match ...
- log4net日记文件路径动态配置
在项目开发过程中,部署的服务器越来越多,查看日记的时候需要每台服务器去找日记看,这对运维人员来说是一个很不友好的方式.在此基础上就提出将所有日记统一到一台服务器上进行存放,并按照产生日记的服务器分文件 ...
- .NET Core 部署到CentOS–1.创建项目,简单部署
开发环境:Windows 10,部署环境:阿里云 CentOS 7.3 1. 创建应用 1) 创建项目, 配置应用生成部署包 2) 配置项目 编辑project.json, 追加环境项, 选项可参考这 ...
- PCA (主成分分析)详解——转载 古剑寒
转载地址:http://my.oschina.net/gujianhan/blog/225241 另外可以参考相关博文:http://blog.csdn.net/neal1991/article/de ...
- PAT 1056 Mice and Rice
#include <cstdio> #include <climits> #include <cstdlib> #include <vector> #i ...
- 从list中随机选出几个数,并按照原来的顺序排列
需求: 从list中随机选出几个数,并按照原来的顺序排列(比如从list中随机选出6个数) 方案一: //若对象size大于6,则随机去除6个对象,并按照原来的顺序排列 while(list.size ...
- toMapFromStage layerDefinitions ClassBreakRenderer
class Map 方法 toMapFromStage 用于把屏幕坐标转换为地理坐标 public function toMapFromStage(stageX:Number, stageY:Numb ...
- UML视频
https://www.bilibili.com/video/av34973179/?p=1 北京 圣思园 UML视频