poj3608Bridge Across Islands(凸包间最小距离)
以下所有文章均转载( http://blog.csdn.net/acmaker/article/details/3176910) 转载请注明出处!
考虑如下的算法, 算法的输入是两个分别有 m 和 n 个顺时针给定顶点的凸多边形 P 和 Q。
- 计算 P 上 y 坐标值最小的顶点(称为 yminP ) 和 Q 上 y 坐标值最大的顶点(称为 ymaxQ)。
- 为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于他们的右侧。 此时 LP 和 LQ 拥有不同的方向, 并且 yminP 和 ymaxQ 成为了多边形间的一个对踵点对。
- 计算距离(yminP,ymaxQ) 并且将其维护为当前最小值。
- 顺时针同时旋转平行线直到其中一个与其所在的多边形的边重合。
- 如果只有一条线与边重合, 那么只需要计算“顶点-边”对踵点对和“顶点-顶点”对踵点对距离。 都将他们与当前最小值比较, 如果小于当前最小值则进行替换更新。 如果两条切线都与边重合, 那么情况就更加复杂了。 如果边“交叠”, 也就是可以构造一条与两条边都相交的公垂线(但不是在顶点处相交), 那么就计算“边-边”距离。 否则计算三个新的“顶点-顶点”对踵点对距离。 所有的这些距离都与当前最小值进行比较, 若小于当前最小值则更新替换。
- 重复执行步骤4和步骤5, 直到新的点对为(yminP,ymaxQ)。
- 输出最大距离。
以上是转载。。以下是原创。。
上面是按顺时针存的凸包也是按顺时针旋转的平行线,网上很多是逆时针的凸包却写着顺时针的做法,但代码依旧A了,,不是很理解。。
逆时针 改反一点 依旧A。。。
感觉自己 的是对的吧。。。
- #include <iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<stdlib.h>
- #include<vector>
- #include<cmath>
- #include<queue>
- #include<set>
- using namespace std;
- #define N 10010
- #define LL long long
- #define INF 0xfffffff
- const double eps = 1e-;
- const double pi = acos(-1.0);
- const double inf = ~0u>>;
- struct Point
- {
- double x,y;
- Point(double x=,double y=):x(x),y(y) {} //构造函数 方便代码编写
- }p[N],q[N];
- typedef Point pointt;
- pointt operator + (Point a,Point b)
- {
- return Point(a.x+b.x,a.y+b.y);
- }
- pointt operator - (Point a,Point b)
- {
- return Point(a.x-b.x,a.y-b.y);
- }
- int dcmp(double x)
- {
- if(fabs(x)<eps) return ;
- else return x<?-:;
- }
- bool operator == (const Point &a,const Point &b)
- {
- return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
- }
- double dot(Point a,Point b)
- {
- return a.x*b.x+a.y*b.y;
- }
- double dis(Point a)
- {
- return sqrt(dot(a,a));
- }
- double cross(Point a,Point b)
- {
- return a.x*b.y-a.y*b.x;
- }
- void anticlock(Point p[],int n)
- {
- for(int i = ; i < n- ; i++)
- {
- double k = cross(p[i+]-p[],p[i+]-p[]);
- if(dcmp(k)>) return ;
- else if(dcmp(k)<)
- {
- reverse(p,p+n);
- return ;
- }
- }
- }
- double distoline(Point a,Point b,Point c)
- {
- if(dcmp(dis(a-b))==) return dis(a-c);
- if(dcmp(dot(a-b,a-c))<) return dis(a-c);
- if(dcmp(dot(b-a,b-c))<) return dis(b-c);
- return fabs(cross(a-b,a-c))/dis(a-b);
- }
- double dist(Point a,Point b,Point c,Point d)
- {
- double ans = distoline(a,b,c);
- ans = min(ans,distoline(a,b,d));
- ans = min(ans,distoline(c,d,a));
- ans = min(ans,distoline(c,d,b));
- return ans;
- }
- double mul(Point a,Point b,Point c)
- {
- return cross(b-a,c-a);
- }
- double solve(Point p[],int n,Point q[],int m)
- {
- int i;
- int miny = ,maxy = ;
- for(i = ;i < n; i++)
- {
- if(p[i].y<p[miny].y)
- miny = i;
- }
- for(i = ; i< m ; i++)
- if(q[i].y>q[maxy].y) maxy = i;
- double ans = dis(p[miny]-q[maxy]);
- for(i = ;i < n; i++)
- {
- double tmp;
- while(tmp = mul(p[miny],p[miny+],q[maxy+])-mul(p[miny],p[miny+],q[maxy])>eps)
- maxy = (maxy+)%m;
- if(dcmp(tmp)>) ans = min(ans,distoline(p[miny],p[miny+],q[maxy]));//这里如果写成<0 画图可以看出是顺时针的做法 就算不加这句直接算下面的也能A。。
- else
- ans = min(ans,dist(p[miny],p[miny+],q[maxy],q[maxy+]));//边-边
- miny = (miny+)%n;
- }
- return ans;
- }
- int main()
- {
- int i,n,m;
- while(scanf("%d%d",&n,&m)&&n&&m)
- {
- for(i = ; i < n ; i++)
- scanf("%lf%lf",&p[i].x,&p[i].y);
- for(i = ;i < m ;i++)
- scanf("%lf%lf",&q[i].x,&q[i].y);
- anticlock(p,n);
- anticlock(q,m);
- p[n] = p[];
- q[m] = q[];
- double ans = min(solve(p,n,q,m),solve(q,m,p,n));
- printf("%.5f\n",ans);
- }
- return ;
- }
poj3608Bridge Across Islands(凸包间最小距离)的更多相关文章
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- poj 3608 凸包间的最小距离
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7632 Accepted: ...
- poj 3608 Bridge Across Islands 两凸包间最近距离
/** 旋转卡壳,, **/ #include <iostream> #include <algorithm> #include <cmath> #include ...
- POJ 3608 凸包间最短距离(旋转卡壳)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11539 Accepted: ...
- 图算法之Floyd-Warshall 算法-- 任意两点间最小距离
1.Floyd-Warshall 算法 给定一张图,在o(n3)时间内求出任意两点间的最小距离,并可以在求解过程中保存路径 2.Floyd-Warshall 算法概念 这是一个动态规划的算法. 将顶点 ...
- POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7202 Accepted: ...
- UVa1453或La4728 凸包+枚举(或旋转卡壳)
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- poj 2187 凸包加旋转卡壳算法
题目链接:http://poj.org/problem?id=2187 旋转卡壳算法:http://www.cppblog.com/staryjy/archive/2009/11/19/101412. ...
- ●POJ 3608 Bridge Across Islands
题链: http://poj.org/problem?id=3608 题解: 计算几何,求两个凸包间的最小距离,旋转卡壳 两个凸包间的距离,无非下面三种情况: 所以可以基于旋转卡壳的思想,去求最小距离 ...
随机推荐
- RAC例子
我个人非常推崇ReactiveCocoa,它就像中国的太极,太极生两仪,两仪生四象,四象生八卦,八卦生万物.ReactiveCocoa是一个高度抽象的编程框架,它真的很抽象,初看你不知道它是要干嘛的, ...
- HDU 5768:Lucky7(中国剩余定理 + 容斥原理)
http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Problem Description When ?? was born, seven ...
- LTS版本的解析
LTS = Long Term Support Long Term Support:长时间支持版本(三年) ,一般的版本支持为18个月
- html+css复习之第1篇
1. 保证在火狐浏览器字体<12px,苹果横屏的时候字体显示大小还是12px html { background: #fff; -webkit-text-size-adjust: 100%; - ...
- MyBatis 判断条件为等于的问题
在用MyBatis操作数据库的时候相信很多人都用到,当在判断null, 大于,大于等于,小于,小于等于,不等于时估计很多都用到,比较容易实现了,这里就省略了,但唯独判断条件为等于时估计蛮多人遇到坑了, ...
- java 1G大文件复制
对比几种复制方法 复制的文件是980m的txt文件 1. FileChannel 方法 代码: public static void mappedBuffer() throws IOExceptio ...
- Android开发中完全退出程序的三种方法
参考: http://android.tgbus.com/Android/tutorial/201108/363511.shtml Android程序有很多Activity,比如说主窗口A,调用了子窗 ...
- Linux 多线程应用中如何编写安全的信号处理函数
http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...
- UVa 10054,欧拉回路
题目链接:https://uva.onlinejudge.org/external/100/10054.pdf 题目链接:http://vjudge.net/contest/132239#proble ...
- WP8.1简单项目 《在线词典》
为什么要做这个词典? 学了正则表达式要运用 增加WP开发熟练度 项目中运用了那些技术? HttpClient 正则表达式 数据绑定 详解 通过http://cn.bing.com/dict/searc ...