poj 3714 - 平面最近点对

题目链接:点击这里

 

解题思路:

在原有的分治算法上加上标记,如果标记不同的则计算距离,不然的话就返回无穷大.

用归并排序再可以省下logn

这题要是卡数据不知道有什么更高深的办法.

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int mx = 2e5 + 10;
const double INF = 1.0*1e30;
int n,m;
struct node
{
	double x,y;
	bool f;
	bool operator < (node A)const
	{
		return x < A.x;
	}
}s[mx],kep[mx];
double dist(node A,node	B)
{
	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double divide(int l,int r)
{
	if(l==r) return INF;
	int mid = (l+r)>>1,tot = 0;
	double X = s[mid].x;
	double d = min(divide(l,mid),divide(mid+1,r)); 
	for(int i=l,j=mid+1;i<=mid;i++){
		while(j<=r&&s[j].y<=s[i].y) kep[tot++] = s[j++];
		kep[tot++] = s[i];
	}
	for(int i=0;i<tot;i++) s[i+l] = kep[i];
	tot = 0;
	for(int i=l;i<=r;i++){
		if(fabs(s[i].x-X)<d)
		kep[tot++] = s[i];
	}
	for(int i=0;i<tot;i++){
		for(int j=i+1;j<tot;j++){
			if(kep[j].y-kep[i].y>d) break;
			if(kep[j].f!=kep[i].f)
			d = min(d,dist(kep[i],kep[j]));
		}
	}
	return d;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%lf%lf",&s[i].x,&s[i].y),s[i].f = 0;
		for(int i=n+1;i<=2*n;i++) scanf("%lf%lf",&s[i].x,&s[i].y),s[i].f = 1;
		sort(s+1,s+1+2*n);
		printf("%.3f\n",divide(1,2*n));	
	}
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值