hdu1007

/*
分析:
    分治法求最近点对。
    分治的过程其实就是线段树,一个砍俩,然后合并时候要处理一下。
    大一刚刷a+b时不会的题,今儿切掉了,深刻体验到sort的确是qsort
的改进版本额,囧~

    其实我挺好奇有多少人和我一样,要期末考试了还是不想预习,还在这儿没心没肺的切水题。。。


                                                         2013-01-08
*/












#include"stdio.h"
#include"string.h"
#include"algorithm"
#include"math.h"
#define N 100011
using namespace std;

int n;
struct Point
{
	double x,y;
}E[N],Temp[N];

bool cmpx(Point a,Point b) {return a.x<b.x;}
bool cmpy(Point a,Point b) {return a.y<b.y;}

double closest(int l,int r)
{
    if(l+1==r) return sqrt((E[l].x-E[r].x)*(E[l].x-E[r].x)+(E[l].y-E[r].y)*(E[l].y-E[r].y));
    else if(l+2==r)
	{
		double a,b,c;
		a=(E[l].x-E[r].x)*(E[l].x-E[r].x)+(E[l].y-E[r].y)*(E[l].y-E[r].y);
		b=(E[l+1].x-E[r].x)*(E[l+1].x-E[r].x)+(E[l+1].y-E[r].y)*(E[l+1].y-E[r].y);
		c=(E[l].x-E[r+1].x)*(E[l].x-E[r+1].x)+(E[l].y-E[r+1].y)*(E[l].y-E[r+1].y);
		if(b<a)	a=c;
		if(c<a)	a=c;
		return sqrt(a);
	}

	int i,j,count,mid; 
	mid=(l+r)>>1;
	double a,b,temp,min;
	a=closest(l,mid);
	b=closest(mid+1,r);
	min=a>b?b:a;

	for(i=l,count=0;i<=r;i++)	if(fabs(E[i].x-E[mid].x)<=min)	Temp[count++]=E[i];
	sort(Temp,Temp+count,cmpy);

	for(i=0;i<count;i++)
	for(j=i+1;j<count;j++)
	{
		a=Temp[j].y-Temp[i].y;
		if(a>=min)	break;
		b=Temp[j].x-Temp[i].x;
		temp=sqrt(a*a+b*b);
		if(temp<min)	min=temp;
	}
	return min;
}
int main()
{
	int i;
	while(scanf("%d",&n),n)
	{
		for(i=0;i<n;i++)	scanf("%lf%lf",&E[i].x,&E[i].y);
		sort(E,E+n,cmpx);
		printf("%.2lf\n",closest(0,n-1)/2);
	}
	return 0;
}


你可能感兴趣的:(hdu1007)