Problem description
Given N(2<=N<=100,000) points on the plane, find the nearest two points, print the minimum distance.
Input
Line 1: an integer N, stands for the total number of points. N lines follow: each line contains a pair of (x, y) which are the coordinates of a point and splited by spaces, each value is no bigger than 1,000,000,000.
Output
Line1: the minimum distance, accurate up to 2 decimal places.
Sample Input 1
2
0 0.5
0 0.5
Sample Output 1
0.00
Sample Input 2
3
0 1
-1 1
-1 0
Sample Output 2
1.00
#include<iostream>
#include<algorithm>
#include<cmath>
#include <iomanip>
using namespace std;
struct point
{
double x, y;
};
point p[100000000];
double dis(point a, point b)
{
double dist= sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
//cout << dist << endl;
return dist;
}
double min(double a, double b)
{
return a < b ? a : b;
}
int cmpx(const point &a, const point &b)
{
if (a.x < b.x)
return 1;
else return 0;
}
int cmpy(const point &a, const point &b)
{
if (a.y < b.y)
return 1;
else return 0;
}
double minimum(int begin, int end)
{
if (end - begin == 1) return dis(p[end],p[begin]);//只有两个点返回距离
if (end - begin == 2) return min( min( dis(p[begin],p[begin+1]), dis(p[begin+1], p[end]) ) , dis(p[begin], p[end]) );//求三个点间最小距离
int mid = (begin + end) / 2;
double minil = minimum(begin,mid);//求左半部分最小
double minir = minimum(mid + 1, end);//右半最小
double minim = min(minil,minir);//取左右两个的最小
sort(&p[begin], &p[end], cmpy);
for (int i = begin; i <= end; i++)
{
int k = (i + 11)<end ? i+11 : end;
for (int j = i + 1; j<k; j++)
{
if (dis(p[i], p[j]) >= minim) break;
minim = min(minim, dis(p[i], p[j]));
}
}
return minim;
}
int main()
{ int n;
cin >> n;
for (int t = 0; t<n; t++)
{
cin >> p[t].x;
cin >> p[t].y;
}
sort(&p[0], &p[n - 1], cmpx);
cout << fixed << setprecision(2)<< minimum(0, n - 1) << endl;
return 0;
}