【题目链接】 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 (旋转卡壳)的更多相关文章

  1. POJ 3608 Bridge Across Islands [旋转卡壳]

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

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

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

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

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

  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. ibeacon UUID

    import sys; import uuid; s=uuid.uuid4().hex #s="f6bc15e0939046679be1866ec8a199dc" sys.stdo ...

  2. ERROR: Found lingering reference file hdfs

    Found lingering reference异常 ERROR: Found lingering reference file hdfs://jiujiang1:9000/hbase/month_ ...

  3. scrapy 为每个pipeline配置spider

    在settings.py里面配置pipeline,这里的配置的pipeline会作用于所有的spider,我们可以为每一个spider配置不同的pipeline, 设置 Spider 的 custom ...

  4. NetTime

    NetTime NetTime is a Simple Network Time Protocol (SNTP) client for Windows 95/98/Me/NT/2000/XP/Vist ...

  5. MDIO/MDC(SMI)接口-leonwang202

    ChinaUnix博客 http://blog.chinaunix.net/uid-24148050-id-132863.html

  6. 【BZOJ2527】【POI2011】Meteors [整体二分]

    Meteors Time Limit: 60 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 这个星球经常会下陨石雨.BI ...

  7. bootstrap-datetimepicker年视图中endDate设置之后比正常时间提前两个月

    问题 bootstrap-datetimepicker年视图中endDate设置结束时间为2016-08,(即8月之后的日期不能选)而在日历上显示时为2016-06,相差两个月,即6月之后的日期不能选 ...

  8. Linux curl命令【curl】

    命令:curl 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具 ...

  9. (转)Vim 脚本语言

    2012 年 10 月 20 日 by name5566 Categories: Computer Science, Tools 参考文献列表: http://vimdoc.sourceforge.n ...

  10. RabbitMQ消息队列(五): 主题分发

    1. 主题(Topics): fanout模式只能进行简单的广播,direct模式虽然在过滤上进行了一定的提升,但是不能支持复杂的条件, 比如我们的日志消息,现在不仅要知道消息级别,也要知道消息来源. ...