hdu1007 找最近点对问题(一)
来源:互联网 发布:合同管理数据库 编辑:程序博客网 时间:2024/05/22 08:08
题目链接:hdu1007
题目大意:给出n个点,求出最近的两个点的距离,最后输出时候这个距离再除以2.
思路:
蛮力算法复杂度很明显为O(N^2)不理想。如果是O(N*logN)就好多了,下面介绍分治算法在解决该问题的具体应用过程。
假设平面上的点按x排序好了,这样最多增加O(N*logN),这再整个算法来看并没有增加复杂度级别。
排好序后,可以划一条垂线,把点集分成两半:PL和PR。于是最近点对或者在PL中,或者在PR中,或者PL,PR各有一点。
把三种距离情况定义为dL, dR, dC.
其中dL, dR可以递归求解,于是问题就变为计算dC。 根据上面红色字解释,由于我们希望得到O(N*logN)的解,因此必须能够仅仅多花O(N)的附加工作计算dC。
另s=min(dL, dR). 通过观察能得出结论:如果dC<s,即dC对s有所改进,则只需计算dC。如果dC满足这样的条件,则决定dC的两点必然在分割线的s距离之内,称之为带(strip)
否则不可能满足dC<s, 于是缩小了需要考虑的点的范围。
如果是均匀分布的点集,则能证明出在该带中平均只有O(sqrt(N))个点。因此,对这些点运用蛮力法可以在O(N)时间内完成。
但是容易TLE,所以需要进行优化。蛮力枚举的话最坏情况复杂度仍会上升至O(N*N), 为了得到O(N*logN)解法,我们仍然需要进行优化。通过进一步观察,我们发现,在带中的点,若进行按y坐标排序后,如果两个点y坐标相差s,则一定不是最短点对,所以只需求y相差不大于s的点对距离即可。
#include <stdio.h>#include <math.h>#include <algorithm>using namespace std;#define N 100001struct Point{ double x,y;}p[N];int arr[N];double Min(double a,double b){ return a<b?a:b;}// 求两点之间的距离double dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}// 根据点横坐标or纵坐标排序bool cmp_y( int a,int b){ return p[a].y<p[b].y;}bool cmp_x( Point a,Point b){ return a.x<b.x;}// 求最近点对double close_pair( int l,int r ){ // 判断两个点和三个点的情况 if( r==l+1 ) return dis( p[l],p[r] ); else if( r==l+2 ) return Min( dis(p[l],p[r]),Min( dis(p[l],p[l+1]),dis(p[l+1],p[r]) ) ); int mid=(l+r)>>1; double ans=Min(close_pair(l,mid),close_pair(mid+1,r)); int i,j,cnt=0; // 如果 当前p[i]点 横坐标位于 范围(中点横坐标-ans,中点横坐标+ans)位置内,则记录点的序号 for(i=l; i<=r; ++i) if( p[i].x>=p[mid].x-ans && p[i].x<=p[mid].x+ans ) arr[cnt++]=i; // 按照纵坐标由小到大 对于arr数组内点进行排序 sort(arr,arr+cnt,cmp_y); for(i=0; i<cnt; i++) for(j=i+1; j<cnt; j++) { if(p[arr[j]].y-p[arr[i]].y>=ans) break; ans=Min(ans,dis(p[arr[i]],p[arr[j]])); } return ans;}int main(){ int i,n; while( scanf("%d",&n)!=EOF && n) { for(i=0;i<n;++i) scanf("%lf%lf",&p[i].x,&p[i].y); // 先将所有点按照横坐标由小到大排序 sort(p,p+n,cmp_x); printf("%.2lf\n",close_pair(0,n-1)/2.0); } return 0;}
阅读全文
0 0
- hdu1007 找最近点对问题(一)
- 最近点对问题(hdu1007)
- HDU1007(最近点对问题)
- HDU1007最近点对问题
- hdu1007最近点对
- HDU1007+最近点对
- hdu1007最近点对
- hdu1007 最近点对
- HDU1007 Quoit Design(最近点对问题)
- HDU1007-Quoit Design&POJ3714-Raid(最近点对问题)
- hdu1007 Quoit Design(最近点对)
- hdu1007最近点对(分治)
- hdu1007.最近点对(分治法)
- hdu1007 平面最近点对
- HDU1007 平面最近点对
- HDU1007经典最近点对
- Quoit Design(hdu1007)最近点对问题。模版哦!
- HDU1007——二维空间最近点对问题(分治)
- 实例化一个对象内存分布结构
- java中输入俩俩单词形成的句子,俩个单词进行互换
- 【Android
- C语言指针
- A-问题收益率
- hdu1007 找最近点对问题(一)
- C语言(Head First C)-4_2:创建小工具:管道和自定义数据流
- linux文件系统挂载
- 蓝创十周年大庆,诚邀创业者共分享
- 这是一个测试
- PHP操作MySQL数据库--PHP的应用
- jquery怎么在点击li标签之后添加一个在class,点击下一个li时删除上一个class?
- 数塔 dp
- 静态成员的相互访问