求点集中的最近点对有以下两种方法:

设p1=(x1, y1), p2=(x2, y2), …, pn=(xn, yn)是平面上n个点构成的集合S,设计算法找出集合S中距离最近的点对。

OJ题目:HDU1007http://acm.hdu.edu.cn/showproblem.php?pid=1007

1、蛮力法(适用于点的数目比较小的情况下)

1)算法描述:已知集合S中有n个点,一共可以组成n(n-1)/2对点对,蛮力法就是对这n(n-1)/2对点对逐对进行距离计算,通过循环求得点集中的最近点对:

2、分治法

1)算法描述:已知集合S中有n个点,分治法的思想就是将S进行拆分,分为2部分求最近点对。算法每次选择一条垂线L,将S拆分左右两部分为SL和SR,L一般取点集S中所有点的中间点的x坐标来划分,这样可以保证SL和SR中的点数目各为n/2,

(否则以其他方式划分S,有可能导致SL和SR中点数目一个为1,一个为n-1,不利于算法效率,要尽量保持树的平衡性)

依次找出这两部分中的最小点对距离:δL和δR,记SL和SR中最小点对距离δ = min(δL,δR),如图1:

以L为中心,δ为半径划分一个长带,最小点对还有可能存在于SL和SR的交界处,如下图2左图中的虚线带,p点和q点分别位于SL和SR的虚线范围内,在这个范围内,p点和q点之间的距离才会小于δ,最小点对计算才有意义。

Figure 2

对于SL虚框范围内的p点,在SR虚框中与p点距离小于δ的顶多只有六个点,就是图二右图中的2个正方形的6的顶点。这个可以反推证明,如果右边这2个正方形内有7个点与p点距离小于δ,例如q点,则q点与下面正方形的四个顶点距离小于δ,则和δ为SL和SR中的最小点对距离相矛盾。因此对于SL虚框中的p点,不需求出p点和右边虚线框内所有点距离,只需计算SR中与p点y坐标距离最近的6个点,就可以求出最近点对,节省了比较次数。

(否则的话,最坏情形下,在SR虚框中有可能会有n/2个点,对于SL虚框中的p点,每次要比较n/2次,浪费了算法的效率)

[cpp] view plaincopy
  1. #include <iostream>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cstdio>
  5. #include <cmath>
  6. using namespace std;
  7. struct point
  8. {
  9. double x,y;
  10. }p[100005];
  11. int a[100005];
  12. int cmpx(const point &a,const point &b)
  13. {
  14. return a.x < b.x;
  15. }
  16. int cmpy(const int &a,const int &b)
  17. {
  18. return p[a].y < p[b].y;
  19. }
  20. double dis(int a,int b)
  21. {
  22. return sqrt((p[a].x - p[b].x) * (p[a].x - p[b].x) + (p[a].y - p[b].y) * (p[a].y - p[b].y));
  23. }
  24. double min(double x,double y)
  25. {
  26. return x < y ? x : y;
  27. }
  28. double cloest(int left, int right)
  29. {
  30. if(left == right)
  31. return 1000000;
  32. if(left + 1 == right)
  33. return dis(left,right);
  34. int mid = (left + right) >> 1;
  35. double d1 = cloest(left,mid);     //递归求左部分最近点距离
  36. double d2 = cloest(mid+1,right);   //右部分
  37. double d = min(d1,d2);
  38. int i,j,k = 0;
  39. for( i = left ; i <= right; i++ )
  40. {
  41. if(fabs(p[mid].x - p[i].x) < d)     //记录和mid位置点小于d的点的位置
  42. a[k++] = i;        //注意这里记录的是位置号
  43. }
  44. sort(a,a+k,cmpy);    //按y坐标排序
  45. for( i = 0; i < k - 1; i++ )
  46. {
  47. for( j = i+1; j < i + 7 && j < k; j++ )
  48. {
  49. if(p[a[j]].y - p[a[i]].y >= d)
  50. break;
  51. d = min(d,dis(a[i],a[j]));
  52. }
  53. }
  54. return d;
  55. }
  56. int main()
  57. {
  58. int i,n;
  59. while(scanf("%d",&n) != 0)
  60. {
  61. if(!n)
  62. break;
  63. for( i = 0; i < n; i++ )
  64. {
  65. scanf("%lf %lf",&p[i].x,&p[i].y);
  66. }
  67. sort(p,p+n,cmpx);    //按x坐标排序
  68. printf("%.2f\n",cloest(0,n-1) / 2);
  69. }
  70. return 0;
  71. }

HDU1007 查找平面最近点对相关推荐

  1. CF429D Tricky Function(求解公式、经分析转为求平面最近点对、思维)

    整理的算法模板合集: ACM模板 目录 CF429D Tricky Function 题意实际上就是给定长度为 nnn 的一串序列a1,a2,...,ana_1, a_2,...,a_na1​,a2​ ...

  2. POJ3714 Raid 平面最近点对

    利用分治来求平面最近点对 只需要查后面6个点就好了 原因在于https://blog.csdn.net/liufeng_king/article/details/8484284 两个集合的话就把不同集 ...

  3. HDU-4631 Sad Love Story 平面最近点对

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4631 数据是随机的,没有极端数据,所以可以分段考虑,最小值是一个单调不增的函数,然后每次分治算平面最近 ...

  4. 平面最近点对问题(分治)

    题目描述 在与联盟的战斗中屡战屡败后,帝国撤退到了最后一个据点. 依靠其强大的防御系统,帝国击退了联盟的六波猛烈进攻. 经过几天的苦思冥想,联盟将军亚瑟终于注意到帝国防御系统唯一的弱点就是能源供应. ...

  5. 平面最近点对问题求解—基于Java语言

    平面最近点对问题求解-基于Java语言 1. 问题描述: 本问题来自<编程之美2.11-寻找最近点对>,文中给出了两种解法:暴力解法,分治解法.其中,暴力解法很简单,求出所有点之间的距离并 ...

  6. 分治法求平面最近点对入门

    一.平面最近点对问题. 平面最近点对:在一个平面上有 n n n个点,求出距离最近的两个点. 平面最近点对是计算几何中一个十分经典且基础的问题,通常采用分治法来解决. 二.直线最近点对的分治法. 在用 ...

  7. HDU 5721 Palace(平面最近点对(分治))

    http://acm.hdu.edu.cn/showproblem.php?pid=5721 n个点,去掉一个点的情况下,最近距离平方之和. 平面最近点对模版题,先求出最近距离,然后找到是哪两个点,然 ...

  8. 【算法分析与设计】平面最近点对(含最近距离、最近点对、第一次分割点集合的输出)

    [问题描述] 给定二维平面上n个点,找其中的一对点,使得在n个点组成的所有点对中,该点对间的距离最小.使用递归与分治策略求解二维平面上的最接近点对问题.假设所有点的集合为S,m为S中所有点的x坐标的中 ...

  9. 平面最近点距离问题(分治法)

    问题描述:给定平面上n个点,每个点坐标分别为(x,y),求其中的一对点,使得在n个点组成的所有点对中,该点对的距离最小. 最简单的做法是找到所有点对的距离,然后求最小值,但这样做效率太低,时间复杂度为 ...

最新文章

  1. 事半功倍系列 javascript
  2. ReMILO:使用短读和长读的参考辅助错配检测算法
  3. Scrapy框架----- Spiders
  4. c语言值传递 地址传递 引用传递参数,C++参数传递(值传递,引用传递)
  5. Android 驱动(2)---MTKAndroid添加驱动模块
  6. windows mobile 上面固定比例图像缩放
  7. Linux 命令(125)—— vmstat 命令
  8. MyCat的安装及基本使用(MySQL分库分表)
  9. docker 部署rabbitmq,k8s部署rabbitmq集群,跟踪和监控rabbitmq
  10. c语言编程单片机网线,【C语言】直播一下单片机编程
  11. 步进电机之步进电机驱动器使用说明
  12. 短视频如何打动用户?从人的欲望出发,吸粉引流很简单
  13. [CSDN] 微软雅黑可能导致的博客侵权问题
  14. 程序员996工作制,逼出了一批牛妈!为牛妈点赞!
  15. Storm之——Metric的使用
  16. 【语音识别】基于动态时间规整(DTW)的孤立字语音识别Matlab源码
  17. HTML Purifier解决XSS问题
  18. Mac苹果电脑 安装virtualBox
  19. UEM“探针”技术及用户体验管理
  20. Remove from Sidebar后找回

热门文章

  1. 【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | Android 端实现 BasicMessageChannel 通信 )
  2. 【Android 安全】DEX 加密 ( Application 替换 | 分析 ContentProvider 组件中调用 getApplication() 获取的 Application 二 )
  3. 列表,集合,元组,字典
  4. github上星星1万多的python教程推荐收藏
  5. NSAssert的使用
  6. jsp+servlet 导出Excel表格
  7. python全栈开发基础【第二十三篇】线程
  8. 最常用的15大Eclipse开发快捷键技巧
  9. 处理json中影响解析的多余引号
  10. VMware安装和使用时遇到的一些小问题及解决方法