poj 3608 Bridge Across Islands
题目:计算两个不相交凸多边形间的最小距离。
分析:计算几何、凸包、旋转卡壳。分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可。
注意:1.利用向量法判断旋转,而不是计算角度;避免精度问题和TLE。
2.遇到平行线段时,需要计算4组点到线段距离,不然会漏掉对踵点对。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath> using namespace std; //点结构
typedef struct pnode
{
double x,y,d;
pnode( double a, double b ) {x = a;y = b;}
pnode(){};
}point;
point T,P[10005],Q[10005]; //线段结构
typedef struct lnode
{
double x,y,dx,dy;
lnode( point a, point b ) {x = a.x;y = a.y;dx = b.x-a.x;dy = b.y-a.y;}
lnode(){};
}line; //叉乘 ab*ac
double crossproduct( point a, point b, point c )
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
} //两点间距离
double dist( point a, point b )
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} //点到线段距离
double dist( point a, point p, point q )
{
line l = line( p, q );
//判断垂足位置
if ( (l.dx*(p.x-a.x)+l.dy*(p.y-a.y))*(l.dx*(q.x-a.x)+l.dy*(q.y-a.y)) < 0 )
return fabs(l.dx*(a.y-l.y)-l.dy*(a.x-l.x))/sqrt(l.dx*l.dx+l.dy*l.dy);
else return min( dist( a, p ), dist( a, q ) );
} //坐标比较
bool cmp1( point a, point b )
{
return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
} //级角比较
bool cmp2( point a, point b )
{
double cp = crossproduct( T, a, b );
if ( !cp ) return a.d < b.d;
else return cp > 0;
} //凸包
int graham( point* p, int n )
{
sort( p+0, p+n, cmp1 );
for ( int i = 1 ; i < n ; ++ i )
p[i].d = dist( p[0], p[i] );
T = p[0];
sort( p+1, p+n, cmp2 ); int top = 1;
for ( int i = 2 ; i < n ; ++ i ) {
while ( top > 0 && crossproduct( p[top-1], p[top], p[i] ) <= 0 ) -- top;
p[++ top] = p[i];
}
p[++ top] = p[0]; return top;
} //利用向量判断夹角
double judge( point a, point b, point c, point d )
{
return crossproduct( c, d, point( c.x+b.x-a.x, c.y+b.y-a.y ) );
} //旋转卡壳
double rotatingcalipers( point* p, point* q, int n, int m )
{
double D = 30000.0;
int R = 0;
for ( int i = 0 ; i < m ; ++ i )
if ( q[i].x >= q[R].x ) R = i;
for ( int L = 0 ; L < n ; ++ L ) {
while ( judge( p[L], p[L+1], q[R], q[R+1] ) < 1e-6 )
R = (R+1)%m;
//两条边平行时,需计算平行线段间最短距离,即四个点到线段的距离
D = min( min( D, dist( p[L], q[R] ) ),
min( min( dist( p[L], q[R], q[R+1] ), dist( q[R], p[L], p[L+1] ) ),
min( dist( p[L+1], q[R], q[R+1] ), dist( q[R+1], p[L], p[L+1] ) ) ) );
} return D;
} int main()
{
int N,M;
while ( scanf("%d%d",&N,&M) && N ) {
for ( int i = 0 ; i < N ; ++ i )
scanf("%lf%lf",&P[i].x,&P[i].y);
for ( int i = 0 ; i < M ; ++ i )
scanf("%lf%lf",&Q[i].x,&Q[i].y); N = graham( P, N );
M = graham( Q, M ); printf("%.5lf\n",rotatingcalipers( P, Q, N, M ));
}
return 0;
}
poj 3608 Bridge Across Islands的更多相关文章
- POJ 3608 Bridge Across Islands [旋转卡壳]
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10455 Accepted: ...
- POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7202 Accepted: ...
- ●POJ 3608 Bridge Across Islands
题链: http://poj.org/problem?id=3608 题解: 计算几何,求两个凸包间的最小距离,旋转卡壳 两个凸包间的距离,无非下面三种情况: 所以可以基于旋转卡壳的思想,去求最小距离 ...
- POJ 3608 Bridge Across Islands(计算几何の旋转卡壳)
Description Thousands of thousands years ago there was a small kingdom located in the middle of the ...
- POJ 3608 Bridge Across Islands (旋转卡壳)
[题目链接] http://poj.org/problem?id=3608 [题目大意] 求出两个凸包之间的最短距离 [题解] 我们先找到一个凸包的上顶点和一个凸包的下定点,以这两个点为起点向下一个点 ...
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- POJ - 3608 Bridge Across Islands【旋转卡壳】及一些有趣现象
给两个凸包,求这两个凸包间最短距离 旋转卡壳的基础题 因为是初学旋转卡壳,所以找了别人的代码进行观摩..然而发现很有意思的现象 比如说这个代码(只截取了关键部分) double solve(Point ...
- poj 3608 Bridge Across Islands 两凸包间最近距离
/** 旋转卡壳,, **/ #include <iostream> #include <algorithm> #include <cmath> #include ...
- poj 3068 Bridge Across Islands
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11196 Accepted: ...
随机推荐
- MVC中Razor视图基本语法(1)
Razor前面,必须要跟前面的有空隙,即空格(多谢一楼提醒,url里面确实不用空格,如果要在url里面只需要@(ViewBag.),加上括号就好了),之后的必须要连贯,否则加小括号 1,在页面中输出单 ...
- MVC中Area的使用
1.Area是什么? MVC 2 中引进了区域的概念,它允许将模型,视图和控制器分成单独的功能节点,换句话说,可以在大型复杂的网站中建立几个区域(模块),每一个区域都有Model,View,Contr ...
- php实现手机拍照上传头像功能
现在手机拍照很火,那么如何使用手机拍照并上传头像呢?原因很简单,就是数据传递,首先手机传递照片信息,这个就不是post传递 也不是get函数传递, 这个另外一种数据格式传递,使用的是$GLOBALS ...
- Google v8 - Hello world
OS:Window 7 1.下载v8 zip:https://github.com/v8/v8,解压zip,重命名v8-master文件夹为v8. 2.下载安装svn:http://tortoises ...
- Net Core Docker
Net Core Docker轻量级的web框架 .net core现在已经有了大的发展,虽然笔者现在已经从事python开发,但是一直在关注.net的发展,在逛博客园的时候,发现有大家都会提到N ...
- ListToDataTable
public static DataTable ToDataTable<T>(IEnumerable<T> collection) { var ...
- iOS面试题16719-b
1. 反转二叉树,不用递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* Tr ...
- IOS webview中cookie的读取与保存-b
Cookie 的读取 将它放在 webViewDidFinishLoad 开始后执行 NSArray *nCookies = [[NSHTTPCookieStorage sharedHTTPCooki ...
- BZOJ 1003: [ZJOI2006]物流运输trans DP+最短路
Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...
- App小样在手机运行了一下
外包公司把App小样的安装包发过来了,我在安卓手机上试了一把,虽然还只有几个静态页面,但安装那一刻还是小激动了一把. 在某美术系MM的帮助下,我基本掌握了原型软件azure. 事实证明,很多东西都是逼 ...