UVA - 10245 The Closest Pair Problem

属于Divide-and-Conquer,算法课老师有讲到,就找个题目试试,思想就是不断的二分。。。考虑合并时的处理。。不解释

//============================================================================
// Name        : uva10245.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Uva10245 in C++, Ansi-style
//============================================================================

#include <iostream>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include <limits>
#include<algorithm>

using namespace std;
const int N=10005;
struct coordination{
	double x,y;
}a[N];
int cmp(struct coordination a,struct coordination b){
	if(a.x==b.x)return a.y<b.y;
	return a.x<b.x;
}
int compare(const void *x,const void *y){
	struct coordination* a=(struct coordination* )x;
	struct coordination* b=(struct coordination* )y;
	if(a->x==b->x)return a->y-b->y;
	return a->x-b->x;
}
void print(int n){
	for(int i=0;i<n;i++)
		cout<<a[i].x<<" "<<a[i].y<<endl;

}
double min(double a,double b){
	return a>b?b:a;
}
double getEucleanDistance(int i,int j){
	return sqrt(((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)));
}
double closestPair(int l,int r){
	if(l+1==r){
		return (numeric_limits<double>::max)();
	}
	int mid=(l+r)/2;
	double dl=closestPair(l,mid);
	double dr=closestPair(mid,r);
	double d=min(dl,dr);
	int count;
	for(int i=l;i<mid;i++){
		if(a[i].x>=a[mid].x-d){
			count=0;
			for(int j=mid;j<r&&count<6;j++){ //比较最多不超过6个点
				if(a[j].x<=a[mid].x+d&&a[j].y>=a[i].y-d&&a[j].y<=a[i].y+d){
					count++;
                    d=min(d,getEucleanDistance(i,j));
				}
			}
		}
	}
	return d;
}
int main() {
	int n;
	while(cin>>n,n){
		for(int i=0;i<n;i++)
			cin>>a[i].x>>a[i].y;
		sort(a,a+n,cmp);//sort t=158,while qsort t=169
		//qsort(a,n,sizeof(a[0]),compare);
		//print(n);
		//cout<<(numeric_limits<double>::max)()<<endl;
		double cd=closestPair(0,n);
		if(cd>=10000)cout<<"INFINITY\n";
		else
			printf("%.4f\n",cd);

	}
	return 0;
}
时间: 2024-10-25 02:28:09

UVA - 10245 The Closest Pair Problem的相关文章

uva 10245 The Closest Pair Problem (暴力+剪枝)

uva 10245 The Closest Pair Problem 题目大意:给出n个点,求出距离最近的两点间的距离.若点与点间的距离都大于10000,输出INFINITY 解题思路:这题的正统做法是分治,偷懒方法是暴力加剪枝.先按x坐标排序,然后fabs(p[i] - p[j]) > ans的点就可以直接跳过了. #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algori

UVa 10245 The Closest Pair Problem (分治)

题意:给定 n 个点,求最近两个点的距离. 析:直接求肯定要超时的,利用分治法,先把点分成两大类,答案要么在左边,要么在右边,要么一个点在左边一个点在右边,然后在左边或右边的好求,那么对于一个在左边一个在右边的,我们可以先求全在左边或右边的最小值,假设是d,那么一个点在左边,一个点在右边,那么横坐标之差肯定小于d,才能替换d,同样的纵坐标也是,并且这样的点并不多,然后就可以先选出来,再枚举. 代码如下: #pragma comment(linker, "/STACK:1024000000,102

uva10245 - The Closest Pair Problem(暴力+剪枝)

题目:uva10245 - The Closest Pair Problem(暴力+剪枝) 题目大意:给出N个点,求这些点中最小的两点距离. 解题思路:把这些点中两两之间的距离都算出来,这样的复杂度是O(n^2),会超时,所以加了一个减枝. 先将所有的点按照x坐标排序.然后在计算的过程中,如果发现要计算的这两点的X坐标之差的绝对值已经大于等于当前的最小值,那么说明后面的点计算距离一定比这个最小值要大. 这题的正解貌似是分治法,可惜没看懂. 代码: #include <stdio.h> #inc

uva10245-The Closest Pair Problem(平面上的点分治)

解析:平面上的点分治,先递归得到左右子区间的最小值d,再处理改区间,肯定不会考虑哪些距离已经大于d的点对,对y坐标归并排序,然后从小到大开始枚举更新d,对于某个点,x轴方向只用考虑[x-d,x+d](x是分的中轴线),y轴方向只用考虑[y-d,y](y是这个点的y值),因为d值一直在变小,所以这个矩形包含的点数很少. 代码 #include<cstdio> #include<cstring> #include<string> #include<vector>

UVA 100 The 3n + 1 problem(超级大水题)

The 3n + 1 problem Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Description Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you

HDU 6697 Closest Pair of Segments (计算几何 暴力)

2019 杭电多校 10 1007 题目链接:HDU 6697 比赛链接:2019 Multi-University Training Contest 10 Problem Description The closest pair of points problem is a well-known problem of computational geometry. In this problem, you are given \(n\) points in the Euclidean plan

uva:10487 - Closest Sums(二分查找)

题目:10487 - Closest Sums 题目大意:给出一组数据,再给出m个查询的数字.要求找到这组数据里的两个数据相加的和最靠近这个查询的数据,输出那两个数据的和. 解题思路:二分查找,这样找到的话,就输出查询的数值,但是要注意找不到的情况:这里最靠近的值不一定是在找不到的时刻的前一次数据,所以要维护最靠近的要查询数的数值. 代码: #include <stdio.h> #include <algorithm> #include <stdlib.h> using

UVa 729 - The Hamming Distance Problem

题目:构造n位01串,其中有m个1的所有组合. 分析:搜索.枚举.可以利用库函数,求解,也可以利用dfs求解:我这里采用位运算计算组合数. 说明:注意库啊! #include <iostream> #include <cstdlib> #include <cstdio> using namespace std; int S[20]; int main() { int T,N,M; while ( cin >> T ) for ( int t = 1 ; t

uva 10245 最近点对问题

分治法的典例 当练手了 神奇的是,使用inplace_merge按说应该是O(n)的算法,但是用sort nlogn的算法反而更快 先上快排版 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int SIZE = 10000+10; const doub