3053:the Closest M Points
Time Limit:10 Sec Memory limit:128 MB
submit:1035 solved:363
[Submit] [Status] [Discuss]
Description
The course of software Design and development practice is objectionable. ZLC is facing a serious problem. There is 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 and points. The Euclidean distance between points P and Q are the length of the line segment connecting them. In Cartesian coordinates, if p = (P1, p2,..., pn) and q = (Q1, Q2,..., QN) is the points in Euclidean N-space, then the Dista nCE from P to Q, or from Q to P are given by:
D (p,q) =d (q,p) =sqrt ((Q1-P1) ^2+ (Q2-P2) ^2+ (Q3-P3) ^2...+ (QN-PN) ^2
Can him solve this problem?
The course of the soft engineering school is very annoying. Comrade ZLC A headache: There are many points in the K-dimensional space, and for some given points, ZLC needs to find and its nearest m-point.
(The distance here refers to Euclidean distance: D (p, q) = d (q, p) = sqrt (Q1-P1) ^ 2 + (Q2-P2) ^ 2 + (Q3-P3) ^ 2 + ... + (QN-PN) ^ 2)
ZLC to play DotA, so I'll trouble you to help solve it ...
"Input"
The first line, two nonnegative integers: points n (1 <= n <= 50000), and Dimension K (1 <= k <= 5).
The next n rows, K integers per line, represent the coordinates of a point.
Next positive integer: number of queries given T (1 <= t <= 10000)
Below 2*t line:
First row, K integers: coordinates for a given point
Second line: Query the nearest M-point (1 <= m <= 10)
The absolute value of all coordinates does not exceed 10000.
There are multiple sets of data.
"Output"
For each query, the output m+1 line:
The first line: "The closest m points is:" M in the query
The next M line represents a point, sorted from near to far.
The guarantee scenario is unique, and the following scenario does not occur:
2 2
1 1
3 3
1
2 2
1
Input
The first line of the text file. There is 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 are 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 Co Ntains, lines. The k integers in the first line represent the given point. In the second line, there are one integer m, the number of closest points you should find,1 <= m <=10. The absolute value of all the coordinates is not being more than 10000.
There is multiple test cases. Process to end of file.
Output
For each query, output m+1 lines:
The first line saying: "The closest m points was:" where M is the number of the points.
The following m lines representing m points, in accordance with the
It is guaranteed that the answer can are only being formed in one ways. The distances from the given point to all the nearest m+1 points is different. That means the input like this:
2 2
1 1
3 3
1
2 2
1
would not exist.
Sample Input
3 2
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
HINT
Source
K-d Tree
Sol
Yes, we saw that the source contained a KD tree, so we naturally wrote the Kdtree. Use a heap to maintain the points that have been saved up, and then bare violence.
#include <algorithm> #include <iostream> #include <string> #include <cstring> #include <
cmath> #include <cstdio> #include <cstdlib> #include <queue> using namespace std;
int n,k,m;
int read () {char C;
BOOL Flag=false; while (C=getchar ()) > ' 9 ' | |
c< ' 0 ') if (c== '-') flag=true;
int res=c-' 0 ';
while ((C=getchar ()) >= ' 0 ' &&c<= ' 9 ') res= (res<<3) + (res<<1) +c-' 0 ';
return flag?-res:res;
} const int n=51000;
int l[n],r[n]; struct CC {int x[6],min[6],max[6];}
A[n],tr[n];
struct DD {int dis,name;
friend bool operator < (DD A,dd b) {return a.dis<b.dis;
}
};
Priority_queue<dd> Q;
int F; BOOL CMP (CC K,CC P) {return p.x[f]>k.x[f];} void build (int &k,int flag,int l,int R) {if (FLAG>=K) flag
-=k;
k=l+r>>1;
F=flag;
Nth_element (A+L,A+K,A+R+1,CMP);
TR[K]=A[K];
if (l<=k-1) build (l[k],flag+1,l,k-1); if (k+1<=r) build (r[K],FLAG+1,K+1,R); for (int i=0;i<k;++i) tr[k].min[i]=min (Tr[k].x[i],min (tr[l[k]].min[i],tr[r[k]].min[i)), Tr[k].max[i]=max (Tr[k]
. X[i],max (Tr[l[k]].max[i],tr[r[k]].max[i]));
} void Insert (int &k,int flag,cc P) {if (!k) {k=++n;
Tr[k]=p;
Return
} if (flag>=k) flag-=k;
F=flag;
int d=cmp (TR[K],P);
if (d) d=r[k];
else D=l[k];
Insert (D,FLAG+1,P);
for (int i=0;i<k;++i) tr[k].min[i]=min (Tr[k].min[i],tr[d].min[i]), Tr[k].max[i]=max (Tr[k].max[i],tr[d].max[i]);
} const int INF=1E9;
int sqr (int x) {return x*x;} int Pre_dis (cc k,cc P) {int res=0;
int C;
for (int i=0;i<k;++i) {c=0;
C+=max (k.min[i]-p.x[i],0);
C+=max (p.x[i]-k.max[i],0);
RES+=SQR (c);
} return res;
} int dis (cc a,cc b) {int res=0;
for (int i=0;i<k;++i) RES+=SQR (A.x[i]-b.x[i]);
return res;
} int num;
void query (int k,int flag,cc P) {int fx,fy,p; Fx=fy=inf;
P=dis (TR[K],P); if (q.size () <num| |
Q.top (). dis>p) {if (Q.size () ==num) Q.pop ();
Q.push ((dd) {p,k});
} if (flag>=k) flag-=k;
if (L[k]) Fx=pre_dis (tr[l[k]],p);
if (R[k]) Fy=pre_dis (tr[r[k]],p); if (fx<fy) {if (Q.top (). dis>fx| |
Q.size () <num) query (L[K],FLAG+1,P); if (Q.top (). dis>fy| |
Q.size () <num) query (R[K],FLAG+1,P); } else {if (Q.top (). dis>fy| |
Q.size () <num) query (R[K],FLAG+1,P); if (Q.top (). dis>fx| |
Q.size () <num) query (L[K],FLAG+1,P);
}} int root;
int b[n];
int main () {//Freopen ("3053.txt", "R", stdin);//Freopen ("3053out.txt", "w", stdout);
for (int i=0;i<6;++i) Tr[0].min[i]=inf,tr[0].max[i]=-inf; N=read ();
K=read ();
while (~SCANF ("%d%d", &n,&k)) {root=0;
for (int. i=1;i<=n;++i) for (int j=0;j<k;++j) a[i].x[j]=read ();
Build (Root,0,1,n); for (int i=1;i<=n;++i)//printf("%d%d%d%d%d\n", tr[i].x[0],tr[i].x[1],tr[i].min[0],tr[i].min[1],tr[i].max[0],tr[i].max[1]);
M=read ();
CC P;
int name;
for (int. i=1;i<=m;++i) {while (!q.empty ()) Q.pop ();
for (int j=0;j<k;++j) p.x[j]=read ();
Num=read ();
Query (ROOT,0,P);
printf ("The closest%d points are:\n", num);
for (int j=1;j<=num;++j) b[j]=q.top (). Name,q.pop (); for (int j=num;j>=1;--j) {for (int l=0;l<k;++l) {pri
NTF ("%d", tr[b[j]].x[l]);
if (l<k-1) printf ("");
} printf ("\ n");
}} for (int i=1;i<=n;++i) l[i]=r[i]=0; }
}