C++编程题目------平面上的最接近点对(分治算法)
题目描述
给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的。
输入格式
第一行一个整数 n,表示点的个数。
接下来 n 行,每行两个实数 x,y ,表示一个点的行坐标和列坐标。
输出格式
仅一行,一个实数,表示最短距离,四舍五入保留 4 位小数。
样例
样例输入 #1
3
1 1
1 2
2 2
样例输出 #1
1.0000
数据范围与提示
对于 100% 的数据,保证0<n<=10000 ,0<=x,y<=1000000000,小数点后的数字个数不超过6 。
代码:
#include<bits/stdc++.h>
using namespace std;
int n;
struct point{
double x,y;
};
point a[10010],tmp[10010];
double ans;
bool cmpx(const point &A,const point &B){
if(A.x==B.x)
return A.y<B.y;
else
return A.x<B.x;
}
bool cmpy(const point &A,const point &B){
if(A.y==B.y)
return A.x<B.x;
else
return A.y<B.y;
}
double dist(point A,point B){
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double f(int L,int R){
double ans=2<<18;
if(L==R)
return ans;
else if(L+1==R){
return dist(a[L],a[R]);
}
else{
int mid=(L+R)>>1;
double ans1=f(L,mid);
double ans2=f(mid+1,R);
// cout<<ans1<<" "<<ans2<<endl;
ans=min(ans1,ans2);
// ans=ans1;
// if(ans>ans2)
// ans=ans2;
int cnt=0;
for(int i=L;i<=R;i++)
if (fabs(a[i].x-a[mid].x)<=ans)
tmp[++cnt]=a[i];
sort(tmp+1,tmp+cnt+1,cmpy);
for(int i=1;i<cnt;i++)
for(int j=i+1;j<=cnt;j++)
if(tmp[j].y-tmp[i].y<=ans)
ans=min(ans,dist(tmp[i],tmp[j]));
return ans;
}
}
int main() {
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].x>>a[i].y;
sort(a+1,a+n+1,cmpx);
//for(int i=1;i<=n;i++)
//cout<<a[i].x<<" "<<a[i].y<<endl;
ans=f(1,n);
cout<<fixed<<setprecision(4)<<ans<<endl;
//print("%.4lf\n",ans);
return 0;
}