Implement the algorithm for the closest pair problem in your favourite lan-
guage.
INPUT: Given n points in a plane.
OUTPUT: the pair with the least Euclidean distance.
分析:
题目给n个点,求距离最近的一对点之间距离。该题主要思想就是分治,先把n个点按x坐标升序排序,然后求左边n/2个和右边n/2个的最近距离,最后进行合并。
根据课堂所讲算法,首先按x坐标升序排序,然后取中位数将序列分割成左右两个子序列,然后递归地分别求两个子序列的点间最短距离。取两个子序列的最短距离之中的小值暂时作为当前整个最小值,然后将序列按照y坐标升序排列,然后扫描两子序列分界处相邻11个点并计算之间距离,取这些距离的最小值再与子序列求得的最小值相比,取最终的最小值,就是最终结果。
代码实现:(C/C++)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 10000
struct point
{
double x , y;
};
point p[N];
double dis(point p1,point p2)
{
return sqrt( (p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y) );
}
double min(double a , double b)
{
return a<b ? a:b;
}
int cmpy(const point &a,const point &b)
{
if(a.y<b.y)
return 1;
else
return 0;
}
int cmpx(const point &a,const point &b)
{
if(a.x<b.x)
return 1;
else
return 0;
}
double closestpair(int l,int h)
{
if(h-l==1) return dis(p[l],p[h]);
if(h-l==2) return min( min( dis(p[l],p[l+1]) , dis(p[l+1],p[h]) ),dis(p[l],p[h]) );
int m=(l+h)/2;
double cl=closestpair(l,m);
double cr=closestpair(m+1,h);
double c=min(cl,cr);
sort(&p[l],&p[h],cmpy);
for(int i=l;i<=h;i++)
{
int k=(i+11)>h? h:(i+11); //只要选取出11个相邻点
for(int j=i+1;j<k;j++)
{
if(dis(p[i],p[j])>=c)
break;
c=min(c,dis(p[i],p[j]));
}
}
return c;
}
void 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<<“各点间最短距离为:”<<closestpair(0,n-1)<<endl;
}