
意甲冠军:给n坐标点。半一对点之间的距离所需的距离最近。
分析:分而治之的方法,最近点。
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std; #define N 100005 double min(double a,double b)
{
return a<b? a:b;
} struct POINT
{
double x,y;
};
POINT point[N],*px[N],*py[N]; double dis(const POINT* p1,const POINT* p2)
{
return sqrt(pow(p1->x-p2->x,2.0)+pow(p1->y-p2->y,2.0));
} bool cmpx(const POINT* p1,const POINT* p2)
{
return p1->x<p2->x;
} bool cmpy(const POINT* p1,const POINT* p2)
{
return p1->y<p2->y;
} double core(int s,int e) //分治法求最小点对核心代码
{
int mid,i,j,cnt;
double ans; if(s+1==e) //仅仅有两个点的情况
return dis(px[s],px[e]);
if(s+2==e) //仅仅有三个点的情况
return min(dis(px[s],px[s+1]),min(dis(px[s+1],px[e]),dis(px[s],px[e])));
mid=(s+e)>>1;
ans=min(core(s,mid),core(mid+1,e)); //递归求解
for(cnt=0,i=s;i<=e;i++) //把x坐标在px[mid].x-ans~px[mid].x+ans范围内的点取出来
if(px[i]->x>=px[mid]->x-ans && px[i]->x<=px[mid]->x+ans)
py[cnt++]=px[i];
sort(py,py+cnt,cmpy); //按y值排序
for(i=0;i<cnt;i++)
for(j=i+1;j<cnt;j++)
{
if(py[j]->y-py[i]->y>=ans)
break;
ans=min(ans,dis(py[i],py[j]));
}
return ans;
} int main()
{
int i,n; while(scanf("%d",&n)!=EOF && n)
{
for(i=0;i<n;i++)
{
scanf("%lf%lf",&point[i].x,&point[i].y);
px[i]=&point[i];
}
sort(px,px+n,cmpx); //按x坐标排序
printf("%.2lf\n",core(0,n-1)/2.0);
}
return 0;
}
版权声明:本文博主原创文章,博客,未经同意不得转载。