刚好课上学了平面最近点对的算法,回来实现以下,恩 ,分治的思想很重要。呵呵,又学会了一个算法。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define eps 1e-8
const int maxn=200001;
const double INF=999999999;
typedef struct point
{
double x,y;
//int flag;
point(){};
}point;
point p[maxn];
int n;
int cmp(double x,double y)
{
if(x==y)return 0;
if(x>y)return 1;
return -1;
}
bool cmp1(point a,point b)
{
if(a.x!=b.x)
return a.x<b.x;
else
return a.y<b.y;
}
bool cmp2(int i,int j)
{
return cmp(p[i].y,p[j].y)<0;
}
double dist(point &a,point &b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int y[maxn],len;
double cp(point p[],int l,int r)//求从l到r这些点的最近点对
{
int i,j;
int mid=(l+r)>>1;
double ret=INF;
if(l>=r)
return ret;
for(i=mid;i>=l&&!cmp(p[i].x,p[mid].x);i--);
double t1=cp(p,l,i);
for(i=mid;i<=r&&!cmp(p[i].x,p[mid].x);i++);
double t2=cp(p,i,r);
if(t1<t2)
ret=t1;
else ret=t2;
len=0;
for(i=l;i<=r;i++)
{
if(fabs(p[i].x-p[mid].x)<ret)
y[++len]=i;
}
sort(y+1,y+len+1,cmp2);
for(i=1;i<=len;i++)
{
int cnt=1;
for(j=i+1;j<=len&&cnt<=7;j++)
{
ret=min(ret,dist(p[y[i]],p[y[j]]));
cnt++;
}
}
return ret;
}
bool check(int n)
{
int i;
for(i=2;i<=n;i++)
{
if(p[i].x==p[i-1].x&&p[i].y==p[i-1].y)
return true;
}
return false;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
int i;
for(i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp1);
if(check(n))
{
printf("0.00\n");
continue;
}
double ans=cp(p,1,n)/2;
printf("%.2lf\n",ans);
}
return 0;
}