Bridge Across Islands
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 10455   Accepted: 3093   Special Judge

Description

Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory of the kingdom consists two separated islands. Due to the impact of the ocean current, the shapes of both the islands became convex polygons. The king of the kingdom wanted to establish a bridge to connect the two islands. To minimize the cost, the king asked you, the bishop, to find the minimal distance between the boundaries of the two islands.

Input

The input consists of several test cases.
Each test case begins with two integers NM. (3 ≤ NM ≤ 10000)
Each of the next N lines contains a pair of coordinates, which describes the position of a vertex in one convex polygon.
Each of the next M lines contains a pair of coordinates, which describes the position of a vertex in the other convex polygon.
A line with N = M = 0 indicates the end of input.
The coordinates are within the range [-10000, 10000].

Output

For each test case output the minimal distance. An error within 0.001 is acceptable.

Sample Input

4 4
0.00000 0.00000
0.00000 1.00000
1.00000 1.00000
1.00000 0.00000
2.00000 0.00000
2.00000 1.00000
3.00000 1.00000
3.00000 0.00000
0 0

Sample Output

1.00000

Source


题意:给出两个凸多边形,求他们之间的最近距离


经典:http://blog.csdn.net/acmaker/article/details/3178696


用一个凸包的边去卡另一个凸包的点
先找到一个凸包p的最低点和另一个凸包q的最高点,这样就有了两条线j,j+1和k,k+1来卡
枚举j,移动k使得两条线差不多平行(用叉积判断;可以发现也是单调的)
然后更新ans,如果平行就是平行线段之间最短距离,否则用点k和线段j,j+1的距离
 
注意要用两次,因为分别用两个凸包去卡对方
 
吐槽:哪里说要5位小数了!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int N=5e4+;
const double INF=1e99;
const double eps=1e-; inline int sgn(double x){
if(abs(x)<eps) return ;
else return x<?-:;
} struct Vector{
double x,y;
Vector(double a=,double b=):x(a),y(b){}
bool operator <(const Vector &a)const{
return sgn(x-a.x)<||(sgn(x-a.x)==&&sgn(y-a.y)<);
}
};
typedef Vector Point;
Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);}
Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);}
bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==&&sgn(a.y-b.y)==;}
double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} double Len(Vector a){return sqrt(Dot(a,a));}
double Len2(Vector a){return Dot(a,a);}
double DisTL(Point p,Point a,Point b){
Vector v1=p-a,v2=b-a;
return abs(Cross(v1,v2)/Len(v2));
}
double DisTS(Point p,Point a,Point b){
if(a==b) return Len(p-a);
Vector v1=p-a,v2=p-b,v3=b-a;
if(sgn(Dot(v2,v3))>) return Len(v2);
else if(sgn(Dot(v1,v3))<) return Len(v1);
else return abs(Cross(v1,v3)/Len(v3));
} int n,m;
Point p[N],q[N];
double RotatingCalipers(Point p[],int n,Point q[],int m){
double ans=INF;
p[n+]=p[];
q[m+]=q[];
int j=,k=,t;
for(int i=;i<=n;i++) if(p[i].y<p[j].y) j=i;
for(int i=;i<=m;i++) if(q[i].y>q[k].y) k=i;
for(int i=;i<=n;i++){
while((t=sgn(Cross(p[j+]-p[j],q[k]-q[k+])))<) k=k%m+;
if(t==){
ans=min(ans,min(DisTS(q[k],p[j],p[j+]),DisTS(q[k+],p[j],p[j+])));
ans=min(ans,min(DisTS(p[j],q[k],q[k+]),DisTS(p[j+],q[k],q[k+])));
}else ans=min(ans,DisTS(q[k],p[j],p[j+]));
j=j%n+;
}
return ans;
} int main(int argc, const char * argv[]) {
while(true){
scanf("%d%d",&n,&m);if(n==&&m==) break;
for(int i=;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=;i<=m;i++) scanf("%lf%lf",&q[i].x,&q[i].y);
double ans=min(RotatingCalipers(p,n,q,m),RotatingCalipers(q,m,p,n));
printf("%.5f\n",ans);
}
}
 

POJ 3608 Bridge Across Islands [旋转卡壳]的更多相关文章

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

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

  2. POJ 3608 Bridge Across Islands(计算几何の旋转卡壳)

    Description Thousands of thousands years ago there was a small kingdom located in the middle of the ...

  3. POJ 3608 Bridge Across Islands (旋转卡壳)

    [题目链接] http://poj.org/problem?id=3608 [题目大意] 求出两个凸包之间的最短距离 [题解] 我们先找到一个凸包的上顶点和一个凸包的下定点,以这两个点为起点向下一个点 ...

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

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

  5. POJ - 3608 Bridge Across Islands【旋转卡壳】及一些有趣现象

    给两个凸包,求这两个凸包间最短距离 旋转卡壳的基础题 因为是初学旋转卡壳,所以找了别人的代码进行观摩..然而发现很有意思的现象 比如说这个代码(只截取了关键部分) double solve(Point ...

  6. ●POJ 3608 Bridge Across Islands

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

  7. poj 3608 Bridge Across Islands

    题目:计算两个不相交凸多边形间的最小距离. 分析:计算几何.凸包.旋转卡壳.分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可. 注意:1.利用向量法判断旋转,而不是计算角度:避免精度问题和TLE. ...

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

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

  9. POJ 2187 Beauty Contest【旋转卡壳求凸包直径】

    链接: http://poj.org/problem?id=2187 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

随机推荐

  1. android新闻App源码、仿微信源码、地图音乐源码等

    Android精选源码 一款实用的休闲类App,新闻视频和技术应有尽有. android实现交互式K线图表源码 android新闻客户端和服务器源码 android MatetialDesign设计 ...

  2. phpcms模板生成原理

    phpcms模板生成原理2009-09-25 16:14PHPCMS是功能强大的网站管理系统.以后有时间,俺要将其管理.使用.再开发等等都理顺出来.这一篇短文先介绍PHPCMS的模板机制. 所谓网站模 ...

  3. c#委托事件入门--第一讲:委托入门

    说起委托,有些刚刚入门c#的人感觉很高大上,没有接触过,但是其实很多人都用过Lambda表达式,实际上Lambda表达式就是一个委托. 关于委托入门有个大神写的很详细:张子阳的博客  C#中的委托和事 ...

  4. [学习OpenCV攻略][011][显示图片]

    学习资料: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/tutorials.html   包含头文件 core.hpp:包含 ...

  5. 基础二 day4

    昨日回顾int bit_lenth()bool int ----> bool 非零True,0 False bool----> True 1 False 0 str ----> bo ...

  6. HDU 1069 Monkey and Banana(DP——最大递减子序列)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=1069 题意描述: 给n块砖,给出其长,宽和高 问将这n块砖,怎样叠放使得满足以下条件使得 ...

  7. Oracle_SQL92_连接查询

    Oracle_SQL92_连接查询   笛卡儿积 --笛卡尔积 select * from emp;----14 select * from dept;----4 select * from emp, ...

  8. PHP开发api接口安全验证

    php的api接口 在实际工作中,使用PHP写api接口是经常做的,PHP写好接口后,前台就可以通过链接获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道 ...

  9. 网站搭建中,怎么区分ASP和PHP

    1:空间支持上 ASP:程序要求比较低,空间只要支持ASP+access即可运行 PHP:配置要求比较高,空间需要支持PHP及数据库,而且程序和数据库是单独的,一般的 unix空间都是这种配置. 2: ...

  10. Linux中rpm命令用法听语音

    rpm 是红帽(RedHat)软件包管理工具,实现类似于 Windows 中的添加/删除程序功能.下面,就来向大家介绍 rpm 命令的用法. 工具/原料 CentOS 一.rpm常用参数 1 rpm ...