UVA-10245 The Closest Pair Problem(最近点对问题)

题目大意:给你在n个在二维平面坐标系上的坐标,要你求出所有坐标中两点间最短的距离。

解析:求平面最近点对的核心思想是分治,用递归实现。

具体操作如下:
如点的个数很多,按现将所有点按x排序,如果x相同按照y排序,并按x坐标平均的分成左右两个部分
分别求出两边的最短距离minl与minr 并令 ans = min(minl,minr)。
求出左右两边的最小值之后,剩下的工作就是合并。
然后根据鸽巢原理:
遍历将当前的(l,l+6)的最小值点和ans比较,求其中的最小值

UVA-10245 The Closest Pair Problem(最近点对问题)_第1张图片

UVA-10245 The Closest Pair Problem(最近点对问题)_第2张图片

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 10010;
struct Node {
	double x,y;
}p[N];
bool cmp(Node a,Node b) {
	if(a.x != b.x) {
		return a.x < b.x;
	}else {
		return a.y < b.y;
	}
}
double dis(Node a,Node b) {
	return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
}
double solve(int l,int r) {
	if(l == r) {
		return INF;
	}
	if(r - l == 1) {
		return dis(p[l],p[r]);
	}
	if(r - l == 2) {
		double d1,d2,d3;
		d1 = dis(p[l],p[l+1]);
		d2 = dis(p[l],p[l+2]);
		d3 = dis(p[l+1],p[l+2]);
		return min(min(d1,d2),d3);
	}
	int mid = (l + r) / 2;
	double curMin = min(solve(l,mid),solve(mid+1,r));
	for(int i = l; i <= r; i++) {
		for(int j = i+1; j <= r && j <= i+5; j++) {
			if(p[j].x - p[i].x > curMin) {
				continue;
			}
			curMin = min(curMin,dis(p[i],p[j]));
		}
	}
	return curMin; 
}
int main() {
	int n;
	while(scanf("%d",&n) != EOF && n) {
		for(int i = 0; i < n; i++) {
			scanf("%lf%lf",&p[i].x,&p[i].y);
		}
		sort(p,p+n,cmp);
		double ans = solve(0,n-1);
		if(ans > 10000) {
			printf("INFINITY\n");
		}else {
			printf("%.4lf\n",ans);
		}
	}
	return 0;
}



你可能感兴趣的:(closest,uva,pair,pro,the,10245)