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 = (p
1, p
2,..., p
n) and q = (q
1, q
2,..., q
n) are two points in Euclidean n-space, then the distance from p to q, or from q to p is given by:
Can you help him solve this problem?
Can you help him solve this problem?
There are multiple test cases. Process to end of file.
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.
3 2 1 1 1 3 3 4 2 2 3 2 2 3 1
M维kdtree
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 5e4+10; const ll inf=(1ll<<60); int n,m; int nowD; int root; int ql[5]; int k; typedef long long ll; struct Node { int id; ll dis; Node(){} Node(int _id,ll _dis):id(_id),dis(_dis){} bool operator < (const Node &rhs) const { return dis<rhs.dis; } }; struct node { int Min[5],Max[5]; int d[5]; int l,r; }t[MAXN]; priority_queue<Node> Q; inline int getint() { int w=0,q=0; char c=getchar(); while((c<'0'||c>'9')&&c!='-') c=getchar(); if(c=='-') q=1,c=getchar(); while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w; } inline ll dist(int p) { ll dis=0; for(int i=0;i<m;i++) { if(ql[i]<t[p].Min[i]) dis+=1ll*(t[p].Min[i]-ql[i])*(t[p].Min[i]-ql[i]); if(ql[i]>t[p].Max[i]) dis+=1ll*(ql[i]-t[p].Max[i])*(ql[i]-t[p].Max[i]); } return dis; } inline bool cmp(node q,node qq) { if(q.d[nowD]==qq.d[nowD]){ for(int i=0;i<m;i++) { if(i==nowD) continue; if(q.d[i]==qq.d[i]) continue; return q.d[i]<qq.d[i]; } } return q.d[nowD]<qq.d[nowD]; } inline void kd_updata(int now) { if(t[now].l) { for(int i=0;i<m;i++) { if(t[t[now].l].Max[i]>t[now].Max[i]) t[now].Max[i]=t[t[now].l].Max[i]; if(t[t[now].l].Min[i]<t[now].Min[i]) t[now].Min[i]=t[t[now].l].Min[i]; } } if(t[now].r) { for(int i=0;i<m;i++) { if(t[t[now].r].Max[i]>t[now].Max[i]) t[now].Max[i]=t[t[now].r].Max[i]; if(t[t[now].r].Min[i]<t[now].Min[i]) t[now].Min[i]=t[t[now].r].Min[i]; } } } inline int kd_build(int l,int r,int D) { int mid=(l+r)/2; nowD=D; nth_element(t+l+1,t+mid+1,t+r+1,cmp); if(l!=mid) t[mid].l=kd_build(l,mid-1,(D+1)%m); if(r!=mid) t[mid].r=kd_build(mid+1,r,(D+1)%m); for(int i=0;i<m;i++) t[mid].Max[i]=t[mid].Min[i]=t[mid].d[i]; kd_updata(mid); return mid; } inline void kd_query(int p) { ll dl,dr,d0=0; for(int i=0;i<m;i++) d0+=(1ll*t[p].d[i]-ql[i])*(t[p].d[i]-ql[i]); if(Q.size()<k) Q.push(Node(p,d0)); else { if(Q.size()==k&&Q.top().dis>d0) { Q.pop(); Q.push(Node(p,d0)); } } if(t[p].l) dl=dist(t[p].l);else dl=inf; if(t[p].r) dr=dist(t[p].r);else dr=inf; if(dl<dr) { if(Q.size()<k||dl<Q.top().dis) kd_query(t[p].l); if(Q.size()<k||dr<Q.top().dis) kd_query(t[p].r); } else { if(Q.size()<k||dr<Q.top().dis) kd_query(t[p].r); if(Q.size()<k||dl<Q.top().dis) kd_query(t[p].l); } } void dfs(int x) { if(x==k+1) return ; Node f=Q.top(); Q.pop(); dfs(x+1); printf("%d",t[f.id].d[0] ); for(int i=1;i<m;i++) printf(" %d",t[f.id].d[i] ); printf("\n"); } int main() { while(~scanf("%d%d",&n,&m)) { memset(t,0,sizeof(t)); for(int i=1;i<=n;i++) for(int j=0;j<m;j++) t[i].d[j]=getint(); root=kd_build(1,n,0); int q; scanf("%d",&q); while(q--){ for(int i=0;i<m;i++) ql[i]=getint(); k=getint(); while(!Q.empty()) Q.pop(); kd_query(root); printf("the closest %d points are:\n",k ); dfs(1); } } }