题目原文:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1186
Given a set of points in a two dimensional space, you will have to find the distance between the closest two points.
Input The input file contains several sets of input. Each set of input starts with an integer N(0 ≤ N ≤ 10000), which denotes the number of points in this set. The next N line contains the coordinates of N twodimensional points. The first of the two numbers denotes the X-coordinate and the latter denotes the Y -coordinate. The input is terminated by a set whose N = 0. This set should not be processed. The value of the coordinates will be less than 40000 and non-negative.
Output
For each set of input produce a single line of output containing a floating point number (with four digits after the decimal point) which denotes the distance between the closest two points. If there is no such two points in the input whose distance is less than 10000, print the line ‘INFINITY’.
题目大意:10000个点,求最近的两点之间的距离。多组数据。
解题思路:因为数据量太大,如果采用枚举的办法肯定超时,所以采用分治法的策略,每次将所有点按照x坐标排序,然后从中分成两边,每边再递归下去计算自己内部的最小值,最后再借助这个最小值作为约束条件,判断一些距离中间轴不超过当前最小值的点之间的距离。因为有当前最小值的束缚,所以每个点需要考虑的点的范围并不大。http://blog.csdn.net/zhang20072844/article/details/6776386 这篇文章中有相关的证明。
AC代码:
/*
@Author: wchhlbt
@Date: 2017/3/1
*/
#include <bits/stdc++.h>
#define Fori(x) for(int i=0;i<x;i++)
#define Forj(x) for(int j=0;j<x;j++)
#define maxn 10005
#define inf 0x3f3f3f3f
#define ONES(x) __builtin_popcount(x)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<double, double> P;
const double eps =1e-8;
const int mod = 1000000007;
const double PI = acos(-1.0);
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
P a[maxn];
int impossible = inf;
double ans;
bool cmp(P r,P s)
{
return r.second<s.second;
}
double solve(P *a, int n)
{
if(n<=1)
return inf;
int m = n/2;
double d = min(solve(a,m),solve(a+m,n-m));
double x = a[m].first;//划分线
//inplace_merge(a,a+m,a+n,cmp);//对两个有序的数列归并排序
sort(a,a+n,cmp);//将所有点按照y排序,也可以使用上面的归并排序
vector<P> b;
for(int i = 0; i<n; i++){
if(fabs(a[i].first-x)>=d) continue;//距离中间轴超过d,可以跳过
for(int j = b.size()-1; j>=0; j--){
double dx = a[i].first - b[j].first;
double dy = a[i].second - b[j].second;
if(dy-d>=eps)//y值相差超过d也可以跳过
break;
d = min(d,sqrt(dx*dx + dy*dy));
}
b.push_back(a[i]);
}
return d;
}
int main()
{
//cin>>n;
ios_base::sync_with_stdio(false);
cin.tie(0);
cout << fixed << setprecision(4);
int n;
while(cin>>n && n){
for(int i = 0; i<n; i++){
cin>>a[i].first>>a[i].second;
}
sort(a,a+n);
double ans = solve(a,n);
if(ans-1e4>=eps)
cout << "INFINITY" << endl;
else
cout << ans << endl;
}
return 0;
}