链接

以下所有文章均转载( http://blog.csdn.net/acmaker/article/details/3176910) 转载请注明出处!

考虑如下的算法, 算法的输入是两个分别有 m 和 n 个顺时针给定顶点的凸多边形 P 和 Q。

  1. 计算 P 上 y 坐标值最小的顶点(称为 yminP ) 和 Q 上 y 坐标值最大的顶点(称为 ymaxQ)。
  2. 为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于他们的右侧。 此时 LP 和 LQ 拥有不同的方向, 并且 yminP 和 ymaxQ 成为了多边形间的一个对踵点对。
  3. 计算距离(yminP,ymaxQ) 并且将其维护为当前最小值。
  4. 顺时针同时旋转平行线直到其中一个与其所在的多边形的边重合。
  5. 如果只有一条线与边重合, 那么只需要计算“顶点-边”对踵点对和“顶点-顶点”对踵点对距离。 都将他们与当前最小值比较, 如果小于当前最小值则进行替换更新。 如果两条切线都与边重合, 那么情况就更加复杂了。 如果边“交叠”, 也就是可以构造一条与两条边都相交的公垂线(但不是在顶点处相交), 那么就计算“边-边”距离。 否则计算三个新的“顶点-顶点”对踵点对距离。 所有的这些距离都与当前最小值进行比较, 若小于当前最小值则更新替换。
  6. 重复执行步骤4和步骤5, 直到新的点对为(yminP,ymaxQ)。
  7. 输出最大距离。

以上是转载。。以下是原创。。

上面是按顺时针存的凸包也是按顺时针旋转的平行线,网上很多是逆时针的凸包却写着顺时针的做法,但代码依旧A了,,不是很理解。。

逆时针 改反一点 依旧A。。。

感觉自己 的是对的吧。。。

  1. #include <iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<stdlib.h>
  6. #include<vector>
  7. #include<cmath>
  8. #include<queue>
  9. #include<set>
  10. using namespace std;
  11. #define N 10010
  12. #define LL long long
  13. #define INF 0xfffffff
  14. const double eps = 1e-;
  15. const double pi = acos(-1.0);
  16. const double inf = ~0u>>;
  17. struct Point
  18. {
  19. double x,y;
  20. Point(double x=,double y=):x(x),y(y) {} //构造函数 方便代码编写
  21. }p[N],q[N];
  22. typedef Point pointt;
  23. pointt operator + (Point a,Point b)
  24. {
  25. return Point(a.x+b.x,a.y+b.y);
  26. }
  27. pointt operator - (Point a,Point b)
  28. {
  29. return Point(a.x-b.x,a.y-b.y);
  30. }
  31. int dcmp(double x)
  32. {
  33. if(fabs(x)<eps) return ;
  34. else return x<?-:;
  35. }
  36. bool operator == (const Point &a,const Point &b)
  37. {
  38. return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
  39. }
  40. double dot(Point a,Point b)
  41. {
  42. return a.x*b.x+a.y*b.y;
  43. }
  44. double dis(Point a)
  45. {
  46. return sqrt(dot(a,a));
  47. }
  48. double cross(Point a,Point b)
  49. {
  50. return a.x*b.y-a.y*b.x;
  51. }
  52. void anticlock(Point p[],int n)
  53. {
  54. for(int i = ; i < n- ; i++)
  55. {
  56. double k = cross(p[i+]-p[],p[i+]-p[]);
  57. if(dcmp(k)>) return ;
  58. else if(dcmp(k)<)
  59. {
  60. reverse(p,p+n);
  61. return ;
  62. }
  63. }
  64. }
  65. double distoline(Point a,Point b,Point c)
  66. {
  67. if(dcmp(dis(a-b))==) return dis(a-c);
  68. if(dcmp(dot(a-b,a-c))<) return dis(a-c);
  69. if(dcmp(dot(b-a,b-c))<) return dis(b-c);
  70. return fabs(cross(a-b,a-c))/dis(a-b);
  71. }
  72. double dist(Point a,Point b,Point c,Point d)
  73. {
  74. double ans = distoline(a,b,c);
  75. ans = min(ans,distoline(a,b,d));
  76. ans = min(ans,distoline(c,d,a));
  77. ans = min(ans,distoline(c,d,b));
  78. return ans;
  79. }
  80. double mul(Point a,Point b,Point c)
  81. {
  82. return cross(b-a,c-a);
  83. }
  84. double solve(Point p[],int n,Point q[],int m)
  85. {
  86. int i;
  87. int miny = ,maxy = ;
  88. for(i = ;i < n; i++)
  89. {
  90. if(p[i].y<p[miny].y)
  91. miny = i;
  92. }
  93. for(i = ; i< m ; i++)
  94. if(q[i].y>q[maxy].y) maxy = i;
  95. double ans = dis(p[miny]-q[maxy]);
  96. for(i = ;i < n; i++)
  97. {
  98. double tmp;
  99. while(tmp = mul(p[miny],p[miny+],q[maxy+])-mul(p[miny],p[miny+],q[maxy])>eps)
  100. maxy = (maxy+)%m;
  101. if(dcmp(tmp)>) ans = min(ans,distoline(p[miny],p[miny+],q[maxy]));//这里如果写成<0 画图可以看出是顺时针的做法 就算不加这句直接算下面的也能A。。
  102. else
  103. ans = min(ans,dist(p[miny],p[miny+],q[maxy],q[maxy+]));//边-边
  104. miny = (miny+)%n;
  105. }
  106. return ans;
  107. }
  108. int main()
  109. {
  110. int i,n,m;
  111. while(scanf("%d%d",&n,&m)&&n&&m)
  112. {
  113. for(i = ; i < n ; i++)
  114. scanf("%lf%lf",&p[i].x,&p[i].y);
  115. for(i = ;i < m ;i++)
  116. scanf("%lf%lf",&q[i].x,&q[i].y);
  117. anticlock(p,n);
  118. anticlock(q,m);
  119. p[n] = p[];
  120.  
  121. q[m] = q[];
  122. double ans = min(solve(p,n,q,m),solve(q,m,p,n));
  123.  
  124. printf("%.5f\n",ans);
  125. }
  126. return ;
  127. }

poj3608Bridge Across Islands(凸包间最小距离)的更多相关文章

  1. POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳

    题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...

  2. poj 3608 凸包间的最小距离

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7632   Accepted:  ...

  3. poj 3608 Bridge Across Islands 两凸包间最近距离

    /** 旋转卡壳,, **/ #include <iostream> #include <algorithm> #include <cmath> #include ...

  4. POJ 3608 凸包间最短距离(旋转卡壳)

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11539   Accepted: ...

  5. 图算法之Floyd-Warshall 算法-- 任意两点间最小距离

    1.Floyd-Warshall 算法 给定一张图,在o(n3)时间内求出任意两点间的最小距离,并可以在求解过程中保存路径 2.Floyd-Warshall 算法概念 这是一个动态规划的算法. 将顶点 ...

  6. POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)

    Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7202   Accepted:  ...

  7. UVa1453或La4728 凸包+枚举(或旋转卡壳)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. poj 2187 凸包加旋转卡壳算法

    题目链接:http://poj.org/problem?id=2187 旋转卡壳算法:http://www.cppblog.com/staryjy/archive/2009/11/19/101412. ...

  9. ●POJ 3608 Bridge Across Islands

    题链: http://poj.org/problem?id=3608 题解: 计算几何,求两个凸包间的最小距离,旋转卡壳 两个凸包间的距离,无非下面三种情况: 所以可以基于旋转卡壳的思想,去求最小距离 ...

随机推荐

  1. RAC例子

    我个人非常推崇ReactiveCocoa,它就像中国的太极,太极生两仪,两仪生四象,四象生八卦,八卦生万物.ReactiveCocoa是一个高度抽象的编程框架,它真的很抽象,初看你不知道它是要干嘛的, ...

  2. HDU 5768:Lucky7(中国剩余定理 + 容斥原理)

    http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Problem Description   When ?? was born, seven ...

  3. LTS版本的解析

    LTS = Long Term Support Long Term Support:长时间支持版本(三年) ,一般的版本支持为18个月

  4. html+css复习之第1篇

    1. 保证在火狐浏览器字体<12px,苹果横屏的时候字体显示大小还是12px html { background: #fff; -webkit-text-size-adjust: 100%; - ...

  5. MyBatis 判断条件为等于的问题

    在用MyBatis操作数据库的时候相信很多人都用到,当在判断null, 大于,大于等于,小于,小于等于,不等于时估计很多都用到,比较容易实现了,这里就省略了,但唯独判断条件为等于时估计蛮多人遇到坑了, ...

  6. java 1G大文件复制

    对比几种复制方法 复制的文件是980m的txt文件 1.  FileChannel 方法 代码: public static void mappedBuffer() throws IOExceptio ...

  7. Android开发中完全退出程序的三种方法

    参考: http://android.tgbus.com/Android/tutorial/201108/363511.shtml Android程序有很多Activity,比如说主窗口A,调用了子窗 ...

  8. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  9. UVa 10054,欧拉回路

    题目链接:https://uva.onlinejudge.org/external/100/10054.pdf 题目链接:http://vjudge.net/contest/132239#proble ...

  10. WP8.1简单项目 《在线词典》

    为什么要做这个词典? 学了正则表达式要运用 增加WP开发熟练度 项目中运用了那些技术? HttpClient 正则表达式 数据绑定 详解 通过http://cn.bing.com/dict/searc ...