Recent point-to-point problem

Source: Internet
Author: User

In the N points on a two-dimensional plane, how to quickly find the nearest pair of points is the problem of the nearest point.

A simple idea is to forcibly enumerate every two points and record the minimum distance. Obviously, the time complexity is O (n ^ 2 ).

This section describes an O (nlognlogn) algorithm. Actually, it is used hereSub-Governance. Divide the set S of N points on the given plane into two subsets S1 and S2, each of which has about n/2 points. Then, recursively find the closest point in each subset. Here, a key question is how to implement the merge steps in the Division and Control Law, that is, how to obtain the closest point in the original set S from the closest point of S1 and S2. If the two points are in S1 and S2, the problem becomes complicated.

To make the problem easier,First, consider one-dimensional scenarios.. In this case, the N points in S are degraded to n real numbers x1, x2,..., xn on the X axis. The closest point is the two real numbers with the smallest difference among the n real numbers. Obviously, you can sort the vertices in order and then perform linear scanning. However, in order to facilitate the promotion to two-dimensional situations, we try to solve this problem using the divide and conquer method.

Suppose we use M to divide s into S1 and S2 sets. In this way, for all P (points in S1) and Q (points in S2), there is P <q.

Recursively locate the closest point pairs {p1, p2} and {Q1, Q2} on S1 and S2, and set

D = min {| p1-p2 |, | q1-q2 |}

It is easy to know that the closest vertex in S is {p1, p2}, {Q1, Q2}, or a {Q3, P3}, as shown in.



 

If the closest point is {Q3, P3}, I .e. | p3-q3 | <D, then the distance between P3 and Q3 and M is not greater than D, and in the range (m-D, d] and (D, M + D] each have only one vertex. In this way, merge can be implemented in linear time.

In this case, the time complexity of the closest point in one dimension is O (nlogn ).

In two-dimensional scenariosSimilarly, the Division and control method is used, but the difficulty lies in how to achieve linear merge?



 

Visible, forming a 2D band interval with a maximum of N points. The merging time is at least N ^ 2 ,. However, vertices in P1 and P2 have the following sparse properties. For any point in P1, vertices in P2 must fall into a d x 2D rectangle, you only need to check up to six points (the Pigeon nest principle ).

In this way, the points in the band interval are sorted by Y coordinates and then scanned linearly. the time complexity of the merge is O (nlogn), which is almost linear.

 

I can't do it without practicing it. After thinking and referring to the online program, I completed the latest point-to-point program and successfully AC it on each OJ.

Poj3714
Zoj2107
Hdu1007

/** Closest point problem, time complexity: O (N * logn) */# include <iostream> # include <cstdio> # include <cstring> # include <cmath> # include <algorithm> using namespace STD; const double INF = 1e20; const int n= 100005; struct point {Double X; Double Y;} Point [N]; int N; int tmpt [N]; bool cmpxy (const point &, const point & B) {if (. x! = B. x) return. x <B. x; return. Y <B. y;} bool cmpy (const Int & A, const Int & B) {return point [A]. Y <point [B]. y;} double min (double A, double B) {return a <B? A: B;} double DIS (int I, Int J) {return SQRT (point [I]. x-point [J]. x) * (point [I]. x-point [J]. x) + (point [I]. y-point [J]. y) * (point [I]. y-point [J]. y);} double closest_pair (INT left, int right) {double D = inf; If (Left = right) return D; If (left + 1 = right) return DIS (left, right); int mid = (left + right)> 1; double d1 = closest_pair (left, mid); double D2 = closest_pair (Mid + 1, right); D = min (D1, D2); int I, j, k = 0; // separate the range for (I = left; I <= right; I ++) {If (FABS (point [Mid]. x-point [I]. x) <= d) tmpt [k ++] = I;} Sort (tmpt, tmpt + k, cmpy); // linear scan for (I = 0; I <K; I ++) {for (j = I + 1; j <K & point [tmpt [J]. y-point [tmpt [I]. Y <D; j ++) {double D3 = DIS (tmpt [I], tmpt [J]); If (D> D3) d = D3 ;}} return D;} int main () {While (true) {scanf ("% d", & N); If (n = 0) break; for (INT I = 0; I <n; I ++) scanf ("% lf", & point [I]. x, & point [I]. y); sort (point, point + N, cmpxy); printf ("%. 2lf \ n ", closest_pair (0, n-1)/2);} return 0 ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.