●POJ 3608 Bridge Across Islands
题链:
http://poj.org/problem?id=3608
题解:
计算几何,求两个凸包间的最小距离,旋转卡壳
两个凸包间的距离,无非下面三种情况:
所以可以基于旋转卡壳的思想,去求最小距离。
(分别用i,j表示A,B凸包上枚举到的点,i的初始位置为A上y最小的顶点,j的初始位置为B上y最大的顶点。)
逆时针枚举凸包A的每一条边$\vec{A_iA_{i+1}}$,然后对另一个凸包B逆时针旋转卡壳,找到第一个$\vec{B_{j+1}B_j}\times\vec{A_iA_{i+1}}\geq0$
然后把$B_j与\vec{A_iA_{i+1}}$贡献答案,如果$\vec{B_{j+1}B_j}平行\vec{A_iA_{i+1}}$,则$B_j和B_{j+1}$都需要贡献答案。
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 10050
using namespace std;
const double eps=1e-8;
int sign(double x){
if(fabs(x)<=eps) return 0;
return x<0?-1:1;
}
struct Point{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
void Read(){scanf("%lf%lf",&x,&y);}
};
typedef Point Vector;
bool operator < (Point A,Point B){return sign(A.x-B.x)<0||(sign(A.x-B.x)==0&&sign(A.y-B.y)<0);}
Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
Point D[MAXN],C1[MAXN],C2[MAXN];
int Andrew(int dnt,Point *C){
int cnt=0,k;
sort(D+1,D+dnt+1);
for(int i=1;i<=dnt;i++){
while(cnt>1&&sign((C[cnt]-C[cnt-1])^(D[i]-C[cnt-1]))<=0) cnt--;
C[++cnt]=D[i];
} k=cnt;
for(int i=dnt-1;i>=1;i--){
while(cnt>k&&sign((C[cnt]-C[cnt-1])^(D[i]-C[cnt-1]))<=0) cnt--;
C[++cnt]=D[i];
}
return cnt-(dnt>1);
}
double GL(Vector A){//Get_Length
return sqrt(A*A);
}
double TA(Point P,Point A,Point B){//Triangle_Area
return fabs((P-A)^(P-B));
}
double DPS(Point P,Point A,Point B){//the_Distance_of_Point_to_Segment
if(sign(GL(B-A))==0) return GL(P-A);
if(sign((P-A)*(B-A))<0) return GL(P-A);
if(sign((P-B)*(A-B))<0) return GL(P-B);
return TA(P,A,B)/GL(B-A);
}
double RC(int ant,Point *A,int bnt,Point *B){//Rotating_Calipers
A[ant+1]=A[1]; B[bnt+1]=B[1];
int i=1,j=1,tmp; double d=1e300;
for(int k=2;k<=ant;k++) if(sign(A[k].y-A[i].y)<0||(sign(A[k].y-A[i].y)==0&&sign(A[k].x-A[i].x)<0)) i=k;
for(int k=2;k<=bnt;k++) if(sign(B[k].y-B[j].y)>0||(sign(B[k].y-B[j].y)==0&&sign(B[k].x-B[j].x)>0)) j=k;
for(int ci=1;ci<=ant;ci++,i=i%ant+1){
while((tmp=sign((A[i+1]-A[i])^(B[j]-B[j+1])))<0) j=j%bnt+1;
d=min(d,DPS(B[j],A[i+1],A[i]));
if(tmp==0) d=min(d,DPS(B[j+1],A[i+1],A[i]));
}
return d;
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)&&(n||m)){
for(int i=1;i<=n;i++) D[i].Read();
n=Andrew(n,C1);
for(int i=1;i<=m;i++) D[i].Read();
m=Andrew(m,C2);
printf("%.5lf\n",min(RC(n,C1,m,C2),RC(m,C2,n,C1)));
}
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 (旋转卡壳)
[题目链接] http://poj.org/problem?id=3608 [题目大意] 求出两个凸包之间的最短距离 [题解] 我们先找到一个凸包的上顶点和一个凸包的下定点,以这两个点为起点向下一个点 ...
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- poj 3608 Bridge Across Islands
题目:计算两个不相交凸多边形间的最小距离. 分析:计算几何.凸包.旋转卡壳.分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可. 注意:1.利用向量法判断旋转,而不是计算角度:避免精度问题和TLE. ...
- 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: ...
随机推荐
- 关于DLL的创建与使用简单描述(C++、C#)
前言 前一段时间在学关于DLL的创建与调用,结果发现网络上一大堆别人分享的经验都有点问题.现在整理分享一下自己的方法. 工具 Microsoft Visual Studio 2017 depends ...
- 敏捷冲刺每日报告——Day2
1.情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起止时间 2017.10.26 00:00 -- 2017.10.27 00:00 讨论时间地点 2017.10.26晚9:30, ...
- TensorFlow问题“The TensorFlow library wasn't compiled to use SSE instructions, but these are available on your machine and could speed up CPU computations.”
出现的问题: 在使用TensorFlow跑官方教程例子时报以下warning: 虽程序能正常跑出结果,但作为一名强迫症患者对此很是不爽,于是查找资料找到隐藏该warning的解决办法. 解决办法: 在 ...
- 将数组写入Plist文件中
-(void)writeToPlist:(NSArray *)uploadingfiles Name:(NSString *)name { NSMutableArr ...
- bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏
http://www.lydsy.com/JudgeOnline/problem.php?id=1095 点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGo ...
- WPF自学入门(十一)WPF MVVM模式Command命令
在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...
- NodeJs实现自定义分享功能,获取微信授权+用户信息
最近公司搞了个转盘抽奖的运营活动,入口放在了微信公众号里,好久没碰过微信了,刚拾起来瞬间感觉有点懵逼....似乎把之前的坑又都重新踩了一遍,虽然过程曲折,不过好在顺利完成了,而且印象也更加深刻了,抽时 ...
- 离线Chrome插件安装文件(crx)的安装方法
离线Chrome插件安装文件(crx)的安装方法 一.正常安装方法 1.开发谷歌浏览器,设置->扩展程序 在打开的谷歌浏览器的扩展管理器中用户可以看到一些已经安装程序的Chrome插件,或者一个 ...
- SpringCloud的服务注册中心(二)注册中心服务端和两个微服务应用客户端
一.构建EurekaServer工程 1.pom.xml 2.application.yml 3. EurekaServerApp.java 4.启动EurekaServer 二.构建部署 Eurek ...
- JS解析JSON字符串
问题描述:后台需要传递给前台一些数据,用于页面数据显示,因为是一些Lable标签,所以数据传递到前台需要解析. 思路:因为数据比较杂乱,所以我选择传递的数据类型是Json格式,但是数据展示时需要解析成 ...