知识点:分治+平面最近点对
全部排好序后:截中点
分别先考虑左右两半 假设左右两半最近点距为d 就再在距离mid d的范围内考虑就可 一层层递归下去时间复杂度不太高
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
struct wz
{
int x,y;
bool k;
}a[200005];
bool cmp(wz x,wz y)
{
if(x.x==y.x)return x.y<y.y;
return x.x<y.x;
}
double dis(int u,int v)
{
return sqrt(1.00*(a[u].x-a[v].x)*(a[u].x-a[v].x)+1.00*(a[u].y-a[v].y)*(a[u].y-a[v].y));
}
double ans(int l,int r)
{
if(l==r)return 2e9;
int mid=(l+r)>>1;
double ret=2e9;
ret=min(ret,min(ans(l,mid),ans(mid+1,r)));
for(int i=mid;i>=l;--i)
{
if(a[mid].x-a[i].x>ret)break;
for(int j=mid;j<=r;++j)
{
if(a[j].x-a[i].x>ret)break;
if(a[j].k!=a[i].k)ret=min(ret,dis(i,j));
}
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].k=0;
}
for(int i=n+1;i<=2*n;++i)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].k=1;
}
sort(a+1,a+2*n+1,cmp);
printf("%.3f\n",ans(1,2*n));
}
return 0;
}