hdu 1007 - Quoit Design

题目:最近点对。

分析:分治。UVa 10245类似物,这里要优化一下计算两个区间各取一点的情况,提高效率。

            在计算两个集合各取一点定位情况同水平方向一样,将点按竖直方向排序,利用单调性;

            减少计算次数可以提高效率。

说明:UVa和uhunt不好上( ⊙ o ⊙ )啊!

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;

typedef struct nodep
{
	double x,y;
}point; 
point P[100004];
point S[100004];

bool cmp1(point a, point b)
{
	return a.x < b.x;
}

bool cmp2(point a, point b)
{
	return a.y < b.y;
}

double dist(point a, point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double mindist(int a, int b)
{
	if (a > b) return 1e100;
	int l = (a+b)/2,r = (a+b)/2,mid = (a+b)/2;
	double d = min(mindist(a, mid-1), mindist(mid+1, b));

	while (l >= a && d > P[mid].x-P[l].x) l --;
	while (r <= b && d > P[r].x-P[mid].x) r ++;
	if (r == l) return 1e100;

	int count = 0;
	for (int i = l+1 ; i < r ; ++ i)
		S[count ++] = P[i];
	sort(S, S+count, cmp2);
	
	for (int i =  0  ; i < count ; ++ i)
	for (int j = i+1 ; j < count ; ++ j) { 
		if (S[j].y - S[i].y > d) break;
		d = min(d,dist(S[i],S[j]));
	}
	
	return d;
}

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, cmp1);
		printf("%.2lf\n",0.5*mindist( 0, n-1 ));
	}
	return 0;
}


你可能感兴趣的:(hdu 1007 - Quoit Design)