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会 ...
随机推荐
- PHP创建自己的Composer包方法
原文地址:http://www.jb51.net/article/137923.htm
- query纠错方法
1. 第一种,在norvig介绍的方法中,详细的阐述了argmaxc P(c|w)的转换和求解办法. 这个概率不好直接算,但可以根据贝叶斯定理等价于argmaxc P(w|c)*P(c) / P(w) ...
- Apache Beam的目标
不多说,直接上干货! Apache Beam的目标 统一(UNIFIED) 基于单一的编程模型,能够实现批处理(Batch processing).流处理(Streaming Processing), ...
- emacs使用笔记
C-h t tutorial [移动基本操作]C-f C-b C-p C-n 前后上下 C-v C-a 行首 C-e行尾C-a 和 C-e 可以将光标移动到"一行"的头部和尾部.M ...
- TreeMap和TreeSet简单应用
建一个实体类并实现Comparable接口重写compareTo方法 public class pojo implements Comparable<pojo> { private int ...
- [转]使用 Razor 进行递归操作
本文转自:http://www.cnblogs.com/zbw911/archive/2013/01/10/2855025.html 做一个菜单,多级的会遇到递归的问题,打算在code中做一个递归方法 ...
- .net生成cookie,读取cookie,创建特性
1.登录或注册成功时生成票据和cookie 注释:__JZY_Common_User_Login_Cookie__:就是为了判断当前登录人(例如:管理员和普通用户,可以定义两个常量,可有可无) 2.读 ...
- 数据库mysql中编码自动生成
call PrGetRuleCodeNoDate('Table_Name'); call PrGetRuleCode('Table_Name');
- dubbo-admin网页管理控制台
由于近段时间在看dubbo,网上找到的这个war包发布到tomcat报错,故从git(https://github.com/apache/incubator-dubbo-ops)上重新下载编译了版本 ...
- 关于Java中用Double型运算时精度丢失的问题
注:转自 https://blog.csdn.net/bleach_kids/article/details/49129943 在使用Java,double 进行运算时,经常出现精度丢失的问题,总是在 ...