编程之美,最近点对问题(二维)。代码如下:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 100005
struct point{
double x;
double y;
}points[N];
int pp[N];
bool comX(point pa, point pb){
return pa.x < pb.x;
}
bool comY(int pa, int pb){
return points[pa].y < points[pb].y;
}
double dis(point pa, point pb){
return sqrt((pa.x - pb.x)*(pa.x - pb.x) + (pa.y - pb.y)*(pa.y - pb.y));
}
double find(int left, int right){
if(left + 1 == right)
return dis(points[left], points[right]);
if(left + 2 == right){
return min(dis(points[left + 1], points[right]), min(dis(points[left], points[right]), dis(points[left], points[left + 1])));
}
int mid = left + ((right - left)>>1);
double ans = min(find(left, mid), find(mid + 1, right));
int cnt = 0;
for(int i = mid; i >= left; i--){
if(points[mid].x - points[i].x >= ans)
break;
pp[cnt++] = i;
}
for(int j = mid + 1; j <= right; j++){
if(points[j].x - points[mid].x >= ans)
break;
pp[cnt++] = j;
}
sort(pp, pp + cnt, comY);
for(int i = 0; i < cnt; ++i){
for(int j = i + 1; j < cnt; ++j){
if(points[pp[j]].y - points[pp[i]].y >= ans)
break;
ans = min(ans, dis(points[pp[i]], points[pp[j]]));
}
}
return ans;
}
int main(){
int n;
while(cin>>n && n != 0){
for(int i=0;i<n;i++)
cin>>points[i].x>>points[i].y;
sort(points,points+n,comX);
printf("%.2lf%\n",find(0,n-1)/2);
}
return 0;
}