⭐分治法⭐

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=2e5+10;
const int INF=0x3f3f3f3f;
int n;
double res;
struct node
{
double x,y;
}v[N],vv[N];
void read()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&v[i].x,&v[i].y);
}
bool cmp(node a,node b) //注意排序 x、y都要排
{
if(a.x!=b.x) return a.x<b.x;
else return a.y<b.y;
}
double dis(node a,node b)
{
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
double solve(node v[],int l,int r) //分治法
{
int mid=(l+r)/2;
int midval=v[mid].x;
if(l==r) return INF; //一定要足够大
else if(r==l+1) return dis(v[l],v[r]);
double res=min(solve(v,l,mid),solve(v,mid+1,r));
// 左边部分 右边部分
//中间部分
int k=1;
for(int i=l;i<r;i++)
{
if(((v[i].x-midval)<res)&&((v[i].x-midval)>-res))
vv[k++]=v[i];
}
//中间部分的所有点都不能只和mid求dis 应是全部两两相比较
for(int i=1;i<k;i++)
{
for(int j=i+1;j<k;j++)
res=min(res,dis(vv[i],vv[j]));
}
return res;
}
int main()
{
read();
sort(v+1,v+n+1,cmp);
printf("%.4lf\n",solve(v,1,n));
return 0;
}
本文介绍了一种使用分治法解决二维平面上点对之间的最小距离问题的算法实现。通过将点集按x坐标排序并递归地分为左右两部分,分别计算左右两侧的最小距离,再检查跨越中线的点对距离,最终找到全局最小距离。

被折叠的 条评论
为什么被折叠?



