分治算法五(最近点对---杭电OJ 1007 Quoit Design)
2013-05-13 19:56
489 查看
1、问题描述
杭电OJ 1007链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007
即给定坐标系上N个点,找到距离最短的两个点。
2、思路解析
----->如果直接利用两两点比较的话,复杂度太高,为O(n^2),会导致超时
----->简化问题:考虑一维数轴上点的情况,如果对这些点排序O(nlgn),那么最后只需要用O(n)时间就可以找到最小距离,所以总的时间复杂度就是O(nlgn)。
----->回到二维:是不是可以先排序再搜索呢?如果仿照一维的情况,会出现什么问题呢?
=====>>先试着根据 x 轴排序,此时平面上的数据点按照 x 轴已经排好了顺序,那么是不是简单的遍历就能找到最小距离呢?
=====>>二维情况下,距离不是单方面决定的,而是由x,y两个坐标一起决定的,在一个方向上距离最短,不代表最终结果距离最短
=====>>难道这样做不行吗?
=====>>可以顺着这个思路做,但是要修正一下。采用分治的方法。先根据 x 轴对数据点排序,然后从中值点对数组一分为二。分别找到左右两个集合中的最短距离。
然后还有可能存在最短距离的位置就是两个集合之间的区域。对于这个区域,可以把范围限制在【mid - D , mid + D】之间以缩小范围。同时对 y 轴排序,
找出范围在D之内的点,这些点都是可能存在最小距离的区域点。
----->时间复杂度:T(n) = 2*T(n/2) + O(n) = O(nlgn)
杭电OJ 1007链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007
即给定坐标系上N个点,找到距离最短的两个点。
2、思路解析
----->如果直接利用两两点比较的话,复杂度太高,为O(n^2),会导致超时
----->简化问题:考虑一维数轴上点的情况,如果对这些点排序O(nlgn),那么最后只需要用O(n)时间就可以找到最小距离,所以总的时间复杂度就是O(nlgn)。
----->回到二维:是不是可以先排序再搜索呢?如果仿照一维的情况,会出现什么问题呢?
=====>>先试着根据 x 轴排序,此时平面上的数据点按照 x 轴已经排好了顺序,那么是不是简单的遍历就能找到最小距离呢?
=====>>二维情况下,距离不是单方面决定的,而是由x,y两个坐标一起决定的,在一个方向上距离最短,不代表最终结果距离最短
=====>>难道这样做不行吗?
=====>>可以顺着这个思路做,但是要修正一下。采用分治的方法。先根据 x 轴对数据点排序,然后从中值点对数组一分为二。分别找到左右两个集合中的最短距离。
然后还有可能存在最短距离的位置就是两个集合之间的区域。对于这个区域,可以把范围限制在【mid - D , mid + D】之间以缩小范围。同时对 y 轴排序,
找出范围在D之内的点,这些点都是可能存在最小距离的区域点。
----->时间复杂度:T(n) = 2*T(n/2) + O(n) = O(nlgn)
/* file: closest */ /* 1、find the closet distance oftwo points */ /* 2、using divide and conquer algorithm */ /* 3、sorting the points by x-coordinate */ /* 4、divide the points into two sets by L: x = mid,where mid is the middle of the points's x-coordinate. set S1:on the left of line L set S2:on the right of line L */ /* 5、conquer the two sets S1 and S2, and find the minimum distance in set S1 and S2. D = min(S1,S2) */ /* 6、combine:the minimum distance can also be finded between set S1 and S2. the x-coordinate is limited in [mid-D,mid+D],and then sort the limited points by y-coordinate. therefore, the y-coordinate is limited in the length of D */ /* problem:HDU OJ 1007*/ #include <iostream> #include <algorithm> #include <cmath> using namespace std; #define MaxNum 100005 /*===================================== Point:struct of a point PointArray:input points PointY :y-coordinate sorting =======================================*/ struct Point { double x,y; }PointArray[MaxNum],PointY[MaxNum]; /*===================================== CmpX:compare of x-coordinate =======================================*/ bool CmpX(Point a,Point b) { return a.x < b.x; } /*===================================== CmpY:compare of y-coordinate =======================================*/ bool CmpY(Point a,Point b) { return a.y < b.y; } /*===================================== Minimun:return the minimum =======================================*/ inline double Minimun(double a, double b) { return (a < b) ? a : b; } /*===================================== Distance:return the distance between point a, b =======================================*/ inline double Distance(Point a, Point b) { double Px = a.x - b.x; double Py = a.y - b.y; return sqrt(Px * Px + Py * Py); } /*===================================== Closest:return the closest distance of the points =======================================*/ double Closest(int left, int right) { //middle of the array int mid = (left + right) >> 1; //Minimun distance double MinD; int i, j, count; //case of two points if((right - left) == 1) return Distance(PointArray[left], PointArray[right]); //case of three points else if((right - left) == 2) { MinD = Minimun(Distance(PointArray[left], PointArray[right]), Distance(PointArray[left + 1], PointArray[right])); return Minimun(Distance(PointArray[left], PointArray[left + 1]), MinD); } //conquer MinD = Minimun(Closest(left, mid), Closest(mid + 1, right)); //find the points of x-coordinate in [mid - MinD, mid + MinD] for(i = left, count = 0; i <= right; i++) if(fabs(PointArray[i].x - PointArray[mid].x) <= MinD) PointY[count++] = PointArray[i]; //sorting PointY by y-coordinate sort(PointY, PointY + count, CmpY); //Attention:==> for 2-D points,must using two-flod (for) to find the every possible point for(i = 0; i < count; i++) for(j = i + 1; j < count; j++) { if(fabs(PointY[i].y - PointY[j].y) >= MinD) break; MinD = Minimun(MinD, Distance(PointY[i], PointY[j])); } return MinD; } void main() { int N, i; double MinD; while(cin>>N,N) { for(i = 0; i < N; i++) scanf("%lf%lf",&PointArray[i].x,&PointArray[i].y); sort(PointArray, PointArray + N, CmpX); MinD = Closest(0,N-1); printf("%.2lf\n",MinD/2); } }
相关文章推荐
- 杭电OJ——1007 Quoit Design(最近点对问题)
- 杭电OJ——1007 Quoit Design(最近点对问题)
- 杭电ACM OJ 1007 Quoit Design 最近点对 分治 递归
- 杭电OJ 1007 Quoit Design
- HDU 1007 Quoit Design(最近点对问题:分治)
- 【几何】HDU 1007 Quoit Design 最近点对
- hdu 1007 Quoit Design 最近点对
- 菜鸟上路 杭电OJ 1007 求平面上两点之间最短距离--分而治之以及关键点的考虑
- hdu 1007 Quoit Design 最近点对
- 【几何】HDU 1007 Quoit Design 最近点对
- hdu 1007 Quoit Design(分治法求最近点对)
- 杭电 ACM 1007 Quoit Design
- hdu 1007 Quoit Design 分治求最近点对
- HDU - 1007 - Quoit Design (分治解平面最近点对)
- Hdu 1007 Quoit Design【最近点对】
- 1007 Quoit Design (杭电)
- HDU 1007 Quoit Design 最近点对问题
- hdu 1007 Quoit Design(平面最近点对)
- hdu 1007 Quoit Design (最近点对、分治)
- 杭电1007 Quoit Design