poj3714

知识点:分治+平面最近点对

全部排好序后:截中点
分别先考虑左右两半 假设左右两半最近点距为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;
}
发布了25 篇原创文章 · 获赞 1 · 访问量 326

猜你喜欢

转载自blog.csdn.net/qq_43665203/article/details/104148358