1. 程式人生 > >求平面兩點最短距離minimum distance

求平面兩點最短距離minimum distance

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;
}