HDU 1007 二维最近点对问题 / 分治

发现两两比较的问题都可以用分治办法解决~~~

很多排序都这样~~

HDU 1007

http://acm.hdu.edu.cn/showproblem.php?pid=1007

问题描述:

找到最小的圆半径,使得每次套中的玩具只能是一个。

就是找最近点对的距离,再除2 ;


#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
struct Point{
	double x , y ;
}p[100005];
int arr[100005];
bool cmpX(const Point& a,const Point& b)
{
	return a.x < b.x ;
}
bool cmpY(const int& a,const int& b)
{
	return p[a].y < p[b].y ;
}
double dis(int a,int b)
{
	return sqrt((p[a].x - p[b].x)*(p[a].x - p[b].x) + (p[a].y - p[b].y)*(p[a].y - p[b].y));
}
double abs(double a,double b)
{
	return (a - b > 0) ? (a - b):(b - a);
} 
double find(int l ,int r)
{
	if(l+1 == r)return dis(l , r);
	if(l + 2 == r)return min(dis(l , r) , min(dis(l+1,r) , dis(l , l+1)));
	int mid = (l + r) >> 1 ;
	double ans = min(find(l , mid),find(mid+1 ,r));  // 分治 
	int cnt = 0 ;
	for(int i = l;i <= r;i++)
	{
		if(abs(p[i].x , p[mid].x) <= ans)
			arr[cnt++] = i ;  //记录中间的点 
	}
	sort(arr , arr + cnt , cmpY);
	for(int i = 0;i < cnt - 1;i++)
		for(int j = i + 1;j < cnt;j++)
		{
			double d = dis(arr[i] , arr[j]);
			if(d >= ans)break;
			ans = min(ans , d);
		}
	return ans ;
}
int main()
{
	int n ;
	while(~scanf("%d",&n)&&n)
	{
		for(int i = 0;i <  n;i++)
			scanf("%lf%lf",&p[i].x,&p[i].y);
		sort(p , p + n , cmpX);	
		printf("%.2lf\n",find(0, n-1)/2);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值