最近点对问题(UVa 10245)(分治)
2017-06-13 21:07
274 查看
给定平面上的n个点,求距离最近的两个点的距离。
限制条件:
1<=n<=10000
思路:假设我们把所有点按x坐标分成了左右两半,那么最近点对的距离就是下面二者的最小值:
(1)2点p和q同属于左半边或右半边时点对(p,q)的距离;
(2)2点p和q属于不同区域时点对(p,q)的距离;
首先,对于(1)可以通过递归计算;对于(2),我们可以利用(1)部分的最小值,不妨记为d,再考虑下面的(2‘):
(2‘)2点p和q属于不同区域时,距离小于d的点对(p,q)的距离;
接下来,我们考虑x坐标:假设将点划分为左右两半的直线为l,其x坐标为x0,那么根据(2‘),到直线l的距离大于等于d的点就没有必要考虑了,我们只需要考虑x坐标满足x0-d<x<x0+d的点即可;考虑y坐标:对于每个点,都只需要考虑与那些y坐标不比自己大的点组成的点对(或比自己大的)(单方向考虑,避免重复计算点对),也就是说,对于y坐标为yp的点,我们只需要考虑y坐标满足yp-d<y<=yp的点即可;
综上所述,我们要检查的点都在x0-d<x<x0+d且yp-d<y<=yp的矩形区域内。
时间复杂度:递归的深度为O(logn),而每一层有O(n)个操作,所以总的复杂度是O(nlogn);
代码:
限制条件:
1<=n<=10000
思路:假设我们把所有点按x坐标分成了左右两半,那么最近点对的距离就是下面二者的最小值:
(1)2点p和q同属于左半边或右半边时点对(p,q)的距离;
(2)2点p和q属于不同区域时点对(p,q)的距离;
首先,对于(1)可以通过递归计算;对于(2),我们可以利用(1)部分的最小值,不妨记为d,再考虑下面的(2‘):
(2‘)2点p和q属于不同区域时,距离小于d的点对(p,q)的距离;
接下来,我们考虑x坐标:假设将点划分为左右两半的直线为l,其x坐标为x0,那么根据(2‘),到直线l的距离大于等于d的点就没有必要考虑了,我们只需要考虑x坐标满足x0-d<x<x0+d的点即可;考虑y坐标:对于每个点,都只需要考虑与那些y坐标不比自己大的点组成的点对(或比自己大的)(单方向考虑,避免重复计算点对),也就是说,对于y坐标为yp的点,我们只需要考虑y坐标满足yp-d<y<=yp的点即可;
综上所述,我们要检查的点都在x0-d<x<x0+d且yp-d<y<=yp的矩形区域内。
时间复杂度:递归的深度为O(logn),而每一层有O(n)个操作,所以总的复杂度是O(nlogn);
代码:
typedef pair<double,double> P;//first保存x坐标,second保存y坐标 //输入 int N; P A[MAX_N]; //用于按y坐标归并的比较函数 bool compare_y(P a,P b){ return a.second<b.second; } //传入的a已经按x坐标排好序了 double closest_pair(P *a,int n){ if(n<=1) return INF; int m=n/2; double x=a[m].first; double d=min(closest_pair(a,m),closest_pair(a+m,n-m));//(1) inplace_merge(a,a+m,a+n,compare_y);//归并两个排好序的数列,STL中inplace_merge函数点击打开链接 //此时,a已经按y坐标排好序了 //(2‘) vector<P> b;//将到直线的距离小于d的顶点加入 for(int i=0;i<n;i++){ if(fabs(a[i].first-x)>=b) continue; //从后往前检查(因为y坐标递增,故倒着检查)b中y坐标相差小于d的点 for(int j=0;j<b.size();j++){ double dx=a[i].first-b[b.size()-j-1].first; double dy=a[i].second-b[b.size()-j-1].second; if(dy>=d) break; d=min(d,sqrt(dx*dx+dy*dy)); } b.push_back(a[i]); } retuen d; } void solve(){ sort(A,A+N);//按x坐标排序 printf("%f\n",closest_pair(A,N)0; }
相关文章推荐
- uva10245 - The Closest Pair Proble(最近点对问题)
- The Closest Pair Problem(UVa 10245) 计算几何+最近点对问题
- uva 10245 最近点对问题
- UVA 10245 The Closest Pair Problem 最近点问题 分治算法
- UVa Problem 10245 The Closest Pair Problem (最近点对问题)
- UVA 10245 The Closest Pair Problem 最近点问题 分治算法
- UVA-10245 The Closest Pair Problem(最近点对问题)
- UVA 10245 The Closest Pair Problem【分治】
- 分治法求最近点对问题
- HDU1007——二维空间最近点对问题(分治)
- UVa 10245 The Closest Pair Problem 分治
- uva 10245(分治)
- 最近点对问题(分治思想的经典应用)
- 最近点对问题的分治算法分析与实现
- [Swust OJ 794]--最近对问题(分治)
- UVA 10245 The Closest Pair Problem(平面最近点对)
- C语言分治(1)___平面最近点对问题
- 【分治】Quoit Design (HDOJ-1007最近点问题)
- zoj2107 最近点对问题 分治思想
- zoj 2107 Quoit Design(最近点对问题,好好思考,分治)