Two-dimensional plane nearest point - Divide and Conquer

Title description
given n points on a two-dimensional plane, find the nearest half of the distance of the two points therein.
Comprising a plurality of sets of input data, Each test n, is the number of points; next n lines, each line point coordinates.
When n represents an input end, an output line of each set of data as a half of a distance nearest two points is zero.
Sample input:
2
0 0
. 1. 1
2
. 1. 1
. 1. 1
. 3
-1.5 0
0 0
0 1.5
0
Output Sample:
0.71
0.00
0.75
Title Analysis:
using thought of partition, the n points sorted by the x-coordinate to mid coordinates bounded into left and right two parts,
 right and left two portions of the seek distance of the nearest point separately and then combined. Determined for the two portions closest distance d,
 the consolidation process should check whether the strip width section 2d has two points belonging to two sets and the distance is smaller than d, most
 probably there are n points, the worst case time merged under is O (n ^ 2). However, the left and right of the point having the sparse nature,
 for any point of the left, right of the point must fall within a rectangle d * 2d, the inspection and at most only 6 points (
 pigeonhole principle) so that the first point of the strip section is sorted according to y coordinate, and a linear scan, so that when combined
 between complexity of O (nlogn).

Code:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
using namespace std;
double MAX = 1e9;
int a,b;
struct Node{
    double x,y;
    int key;
};
Node ar[1000005],br[1000005];
bool cmpx(Node a,Node b){
    return a.x<b.x;
}
bool cmpy(Node a,Node b){
    return a.y<b.y;
}
double dis(Node a,Node b){
    return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
double min(double a,double b){
    return a<b?a:b;
}
double cal(int s,int e){
    if(s==e)
        return MAX;
    int mid;
    mid = (s+e)/2;
    double d;
    d = min(cal(s,mid),cal(mid+1,e));
    int cnt = 0;
    for(int i=mid;i>=s&&ar[mid].x-ar[i].x<d;i--){
        br[cnt++] =  ar[i];
    }
    for(int i=mid+1;i<=e&&ar[i].x-ar[mid].x<d;i++){
        br[cnt++] = ar[i];
    }
    sort(br,br+cnt,cmpy);
    for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(d>dis(br[i],br[j]))
                d = dis(br[i],br[j]);
        }
    }
    return d;
}

int main(){
    int n;
    while(cin>>n&&n){
        for(int i=1;i<=n;i++){
            scanf("%lf %lf",&ar[i].x,&ar[i].y);
            ar[i].key = i;
        }
        sort(ar+1,ar+n+1,cmpx);
        double d = cal(1,n);
        printf("%.2lf\n",d/2.0);    
    }
    return 0;
}

Ideas:

Using the partition is thought, according to the x-axis into two halves, respectively, and then find the minimum distance between two points min, but note: there may be a bit on both sides, respectively, and the minimum distance, so we want to separate the smallest of the sections seeking out value for comparison in order to determine the overall minimum distance between the two-dimensional space, due to the relatively small section of this point, so we use two for loops will not time out.

 

Guess you like

Origin www.cnblogs.com/lusiqi/p/11576044.html