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会 ...
随机推荐
- logrtate 切割详解
Logrotate是Linux下一款日志管理工具,可用于日志文件的转储(即删除旧日志文件,创建新日志文件).可以根据日志大小或者按照某时段间隔来转储,内部使用cron程序来执行.Logrotate还可 ...
- python 爬虫系列08-同步斗图一波
一波大图来袭 import requests from lxml import etree from urllib import request import os import re def par ...
- 剑指offer第3题:从尾到头打印链表
方法一:采用栈来存储,用ArrayList保存.注意题目给出的输出结果是ArrayList import java.util.ArrayList; import java.util.Stack; pu ...
- nodejs基础知识查缺补漏
1. 单线程.异步I/O.对比php nodejs是单线程的,但是是异步I/O,对于高并发时,它也能够快速的处理请求,100万个请求也可以承担,但是缺点是非常的耗内存,但是我们可以加大内存, 所以能用 ...
- C#(Winform)的SaveFileDialog(文件保存对话框)控件使用
#region 保存对话框 private void ShowSaveFileDialog() { //string localFilePath, fileNameExt ...
- Mavne 打包时出现程序包找到不的问题
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactI ...
- 【转】CentOS6下安装mysql后,重置root密码方法
本文转自:CentOS6下安装mysql后,重置root密码方法 centos下安装mysql,居然不知道root用户密码,本想重装,不过还是先度娘了一些,发现这篇文章,刚好解决我的燃眉之急,太赞了. ...
- 《Python编程从入门到实践》_第二章_变量和简单数据类型
什么是变量 举例: >>> message = "Hello,Python!" >>> print (message) Hello,Python ...
- UML建模—EA创建Class(类图)
1.新建类图 2.添加类或接口 在类图可以捕获系统-类-和模型组件的逻辑结构.它是一个静态模型,描述存在什么,有哪些属性和行为,而不管如何去做. 说明关系之间的类和接口; 泛化. 聚合和关联是在分别反 ...
- 10、选择框:ion-select
!重点 multiple="true" 控制 选择框是 多选还是单选.true为 多选类似 checkbox. /* ---html----*/ <ion-content p ...