POJ 3608 Bridge Across Islands (旋转卡壳)
【题目链接】 http://poj.org/problem?id=3608
【题目大意】
求出两个凸包之间的最短距离
【题解】
我们先找到一个凸包的上顶点和一个凸包的下定点,以这两个点为起点向下一个点画线,
做旋转卡壳,答案一定包含在这个过程中
【代码】
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
double EPS=1e-10;
const double INF=0x3F3F3F3F;
const double PI=acos(-1.0);
double add(double a,double b){
if(abs(a+b)<EPS*(abs(a)+abs(b)))return 0;
return a+b;
}
struct P{
double x,y;
P(){}
P(double x,double y):x(x),y(y){}
P operator + (P p){return P(add(x,p.x),add(y,p.y));}
P operator - (P p){return P(add(x,-p.x),add(y,-p.y));}
P operator * (double d){return P(x*d,y*d);}
double dot(P p){return add(x*p.x,y*p.y);} //点积
double det(P p){return add(x*p.y,-y*p.x);} //叉积
};
bool cmp_y(const P& p,const P& q){
if(p.y!=q.y)return p.y<q.y;
return p.x<q.x;
}
double dist(P p,P q){return sqrt((p-q).dot(p-q));}
double cross(P a, P b,P c){return(b-a).det(c-a);}
double multi(P a,P b,P c){return(b-a).dot(c-a);}
// 点到线段距离
double point_to_line(P a,P b,P c){
if(dist(a,b)<EPS)return dist(b,c);
if(multi(a,b,c)<-EPS)return dist(a,c);
if(multi(b,a,c)<-EPS)return dist(b,c);
return fabs(cross(a,b,c)/dist(a,b));
}
// 线段到线段距离
double line_to_line(P A,P B,P C,P D){
double a=point_to_line(A,B,C);
double b=point_to_line(A,B,D);
double c=point_to_line(C,D,A);
double d=point_to_line(C,D,B);
return min(min(a,b),min(c,d));
}
void anticlockwise_sort(P* p,int N){
for(int i=0;i<N-2;i++){
double tmp=cross(p[i],p[i+1],p[i+2]);
if(tmp>EPS)return;
else if(tmp<-EPS){
reverse(p,p+N);
return;
}
}
}
const int MAX_N=10000;
int n,m;
P ps[MAX_N],qs[MAX_N];
void solve(){
for(int i=0;i<n;i++)scanf("%lf%lf",&ps[i].x,&ps[i].y);
for(int i=0;i<m;i++)scanf("%lf%lf",&qs[i].x,&qs[i].y);
anticlockwise_sort(ps,n);
anticlockwise_sort(qs,m);
int i=0,j=0;
for(int k=0;k<n;k++)if(!cmp_y(ps[i],ps[k]))i=k;
for(int k=0;k<n;k++)if(cmp_y(qs[j],qs[k]))j=k;
double res=INF;
ps[n]=ps[0]; qs[m]=qs[0];
for(int k=0;k<n;k++){
while(cross(ps[i+1],qs[j+1],ps[i])-cross(ps[i+1],qs[j],ps[i])>EPS)j=(j+1)%m;
res=min(res,line_to_line(ps[i],ps[i+1],qs[j],qs[j+1]));
i=(i+1)%n;
}printf("%.5lf\n",res);
}
int main(){
while(~scanf("%d%d",&n,&m)&&n+m)solve();
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(计算几何の旋转卡壳)
Description Thousands of thousands years ago there was a small kingdom located in the middle of the ...
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- POJ - 3608 Bridge Across Islands【旋转卡壳】及一些有趣现象
给两个凸包,求这两个凸包间最短距离 旋转卡壳的基础题 因为是初学旋转卡壳,所以找了别人的代码进行观摩..然而发现很有意思的现象 比如说这个代码(只截取了关键部分) double solve(Point ...
- ●POJ 3608 Bridge Across Islands
题链: http://poj.org/problem?id=3608 题解: 计算几何,求两个凸包间的最小距离,旋转卡壳 两个凸包间的距离,无非下面三种情况: 所以可以基于旋转卡壳的思想,去求最小距离 ...
- poj 3608 Bridge Across Islands
题目:计算两个不相交凸多边形间的最小距离. 分析:计算几何.凸包.旋转卡壳.分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可. 注意:1.利用向量法判断旋转,而不是计算角度:避免精度问题和TLE. ...
- poj 3608 Bridge Across Islands 两凸包间最近距离
/** 旋转卡壳,, **/ #include <iostream> #include <algorithm> #include <cmath> #include ...
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
链接: http://poj.org/problem?id=2187 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
随机推荐
- HDU 2844 二进制优化的多重背包
Coins Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 工作总结-js插件
因最近工作需要,使用了一些js插件,感觉还不错,记录下来以便以后使用. 1.图片轮播插件: 扩展:梦想天空系列:http://www.cnblogs.com/lhb25/archive/2013/01 ...
- (转)Python中实现带Cookie的Http的Post请求
转自crifan: http://www.crifan.com/python_http_post_request_with_cookie/ . . . .
- Hibernate 懒加载 错误----no session
错误: unable to evaluate the expression Method threw 'org.hibernate.LazyInitializa org.hibernate.LazyI ...
- 最适合初学者学习的idea教程
https://github.com/judasn/IntelliJ-IDEA-Tutorial
- 【uva11019-Matrix Matcher】AC自动机+优化+记录
http://acm.hust.edu.cn/vjudge/problem/33057 题意:在二维文本串T中查找一个二维模板串P出现了多少次. 题解: 拆分模板串P的每一行,建AC自动机.拆分文本串 ...
- Vue 还是 React 还是 Angular ?
有空的时候还是把3个都熟悉一下.除了Angular学习起来笔记花时间外.React跟Vue没啥难度,学习用的时间不多. 如果你在Google工作:Angular如果你喜欢TypeScript:Angu ...
- mysql五:数据操作
一 介绍 MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的 ...
- Linux-进程间通信(二): FIFO
1. FIFO: FIFO也被成为命名管道,因其通过路径关系绑定,可以用于任意进程间通信,而普通无名管道只能用于有共同祖先的进行直接通信; 命名管道也是半双工的,open管道的时候不要以读写方式打开, ...
- Linux下进程描述(1)—进程控制块【转】
转自:http://www.cnblogs.com/33debug/p/6705391.html 进程概念介绍 进程是操作系统对运行程序的一种抽象. • 一个正在执行的程序: • 一个正在计算机上执行 ...