hdu1007 平面最近点对

//hdu1007 平面最近点对、


//第一次接触平面的最近点对,暴力果断过不了。
//解题思路:先按一个坐标轴进行排序比如x轴(若x坐标相同按y排序),
//用分冶按x轴把点集分成两块,找出每一块的最近点对然后合并,
//在合并过程中还要考虑由两个不同块构成的点对,
//这里比较重要的是对所要比较的点要在之前求出最小距离的基础下筛选


//代码如下 :


//PS:在这题发现了严重的问题,用#define min(a,b) (a<b? a:b)超时了好多次
//看来以后都不用这个了,还是写个函数来得快。

#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#define eps 1e-8
#define INF 1e20
using namespace std;
struct point { double x,y;};
int  n;
point p[100002];
int temp[100002];


bool  cmpx(const int &a,const int &b){return p[a].x> p[b].x;}
bool  cmpy(const int &a,const int &b){return p[a].y> p[b].y;}
bool  cmpxy(const point &a,const point &b)
{
	if(a.x!=b.x)return a.x>b.x;
	else return a.y>b.y;
} 


double Min(double a, double b) 
{  
    return a < b ?a : b;  
}  
double distance(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 nearPair(int left,int right)
{
	double dis=INF;
	if(left==right)
		return dis;
	if(left+1==right)
		return distance(left,right);
	
	
	int mid=(left+right)>>1;
	dis=Min(dis,nearPair(left,mid));
	dis=Min(dis,nearPair(mid+1,right));
	int i,j,k=0;
	for(i=left;i<=right;i++)
	{
		if(fabs(p[mid].x-p[i].x)<=dis)
			temp[k++]=i;
	}
	sort(temp,temp+k,cmpy);
	for(i=0;i<k;i++)
	{
		for(j=i+1;j<k&&fabs(p[temp[j]].y-p[temp[i]].y)<dis;j++)
		{
			dis=Min(dis,distance(temp[i],temp[j]));
		}
	}
	return dis;
}


int main()
{
	while(scanf("%d",&n),n)
	{
		int i;
		for(i=0;i<n;i++)
			scanf("%lf%lf",&p[i].x,&p[i].y);
		sort(p,p+n,cmpxy);
		printf("%.2lf\n",nearPair(0,n-1)/2.0);
	}
	return 0;
}


 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值