「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
题目链接 POJ-3608 Bridge Across Islands
题意
依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离。
题解
旋转卡壳的应用之一:求两凸包的最近距离。
找到凸包 p 的 y 值最小点 yminP 和 q 的 y 值最大点ymaxQ,然后分别做切线如图。
那么\(AC\times AD> AC\times AB\)则说明B还不是离AC最近的点,所以++ymaxQ。
否则用 \(AC\) 和 \(BD\) 两个线段的距离更新最近距离,并且++yminP,即考察P的下一条边。
代码
#include <cstdio>
#include <cmath>
#include <algorithm>
#define sqr(x) (x)*(x)
#define N 50001
#define EPS (1e-8)
#define PI acos(-1.0)
#define INF (1e99)
using namespace std;
int sgn(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){}
Point operator -(const Point &b)const {
return Point(x - b.x,y - b.y);
}
Point operator +(const Point &b)const {
return Point(x + b.x,y + b.y);
}
double operator ^(const Point &b)const {
return x*b.y - y*b.x;
}
double operator *(const Point &b)const {
return x*b.x + y*b.y;
}
void in(){
scanf("%lf%lf",&x,&y);
}
};
double dis2(Point a,Point b){
return sqr(a-b);
}
double dist(Point a,Point b){
return sqrt(dis2(a,b));
}
struct Line {
Point s,e;
Line(){}
Line(Point _s,Point _e):s(_s),e(_e) {}
};
double xmult(Point a,Point b,Point o){
return (a-o)^(b-o);
}
double mult(Point a, Point b, Point o){
return (a-o)*(b-o);
}
double disToSeg(Point P,Line L){
if(!sgn(dis2(L.s,L.e)))
return dist(L.s,P);
if(sgn(mult(P,L.e,L.s))<0)return dist(L.s,P);
if(sgn(mult(P,L.s,L.e))<0)return dist(L.e,P);
return fabs(xmult(P,L.s,L.e))/dist(L.s,L.e);
}
double segToSeg(Line l1,Line l2){
return min(min(disToSeg(l1.s,l2),disToSeg(l1.e,l2)),min(disToSeg(l2.s,l1),disToSeg(l2.e,l1)));
}
Point p[N],q[N];
int n,m;
double qiake(){
int yminp=0,ymaxq=0;
for(int i=1;i<n;++i)
if(p[i].y<p[yminp].y)
yminp=i;
for(int i=1;i<m;++i)
if(q[i].y>q[ymaxq].y)
ymaxq=i;
p[n]=p[0];
q[m]=q[0];
double tmp,ans=INF;
for(int i=0;i<n;++i){
while(tmp=sgn(xmult(p[yminp+1],q[ymaxq+1],p[yminp])
-xmult(p[yminp+1],q[ymaxq],p[yminp]))>0)
ymaxq=(ymaxq+1)%m;
ans=min(ans,segToSeg(Line(p[yminp],p[yminp+1]),Line(q[ymaxq],q[ymaxq+1])));
yminp=(yminp+1)%n;
}
return ans;
}
int main(){
while(~scanf("%d%d",&n,&m)&&n&&m){
for(int i=0;i<n;++i)
p[i].in();
for(int i=0;i<m;++i)
q[i].in();
printf("%f\n",qiake());
}
return 0;
}
「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)的更多相关文章
- POJ3608(旋转卡壳--求两凸包的最近点对距离)
题目:Bridge Across Islands 分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696 考虑如下的算法, 算法的 ...
- POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7202 Accepted: ...
- POJ 3608 Bridge Across Islands [旋转卡壳]
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10455 Accepted: ...
- poj 3608 旋转卡壳求不相交凸包最近距离;
题目链接:http://poj.org/problem?id=3608 #include<cstdio> #include<cstring> #include<cmath ...
- poj 3608(旋转卡壳求解两凸包之间的最短距离)
Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9768 Accepted: ...
- 旋转卡壳求两个凸包最近距离poj3608
#include <iostream> #include <cmath> #include <vector> #include <string.h> # ...
- POJ2187 旋转卡壳 求最长直径
给定平面上的一些散点集,求最远两点距离的平方值. 题解: 旋转卡壳求出凸包,然后根据单调性,求出最远两点的最大距离 #pragma GCC optimize(2) #pragma G++ optimi ...
- 「POJ 3666」Making the Grade 题解(两种做法)
0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
链接: http://poj.org/problem?id=2187 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
随机推荐
- ES6 Promise 详解
一.概念 Promise,从语法上来讲,它是一个对象,是一个构造函数,可以获取 异步操作 的信息. 简单来讲,就是用同步的方式写异步代码,用来解决回调问题. 二.特点 Promise 对象有两个特点: ...
- C++入门之初话多态与虚函数
多态性是面向对象程序设计的又一个重要思想,关于多态的详尽描述,请看本人的收藏https://www.cnblogs.com/hust-ghtao/p/3512461.html.这篇博文中,详尽的探讨了 ...
- Python编码与变量
(一)Python执行的方式 Window: 在CMD里面,使用 Python + 相对路径/绝对路径 在解释器里面,直接输入,一行代码一行代码的解释 Linux: 明确地指出用Python解释器来执 ...
- java 8中抽象类与接口的异同
1.java 8中抽象类与接口的异同 相同点: 1)都是抽象类型: 2)都可以有实现方法(以前接口不行): 3)都可以不需要实现类或者继承者去实现所有方法,(以前不行,现在接口中默认方法不需要实现者实 ...
- 学习mongoDB的一些感受(转自:http://blog.csdn.net/liusong0605/article/details/11581019)
曾经使用过mongoDB来保存文件,最一开始,只是想总结一下在开发中如何实现文件与mongoDB之间的交互.在此之前,并没有系统的了解过mongoDB,虽然知道我们用它来存储文件这些非结构化数据,但是 ...
- 使用redis限制ip访问次数
策略1: 在redis中保存一个count值(int),key为user:$ip,value为该ip访问的次数,第一次设置key的时候,设置expires. count加1之前,判断是否key是否存在 ...
- c# winform导出Excel
//需要注意添加引用Microsoft.Office.Interop.Excel.dll string fileName =DateTime.Now.Year+ DateTime.Now.Month+ ...
- 二、npm scripts
一.执行原理 安装npm 包,会将其package.json bin 字段添加到node_modules bin 里面,创建对应的.cmd文件,因此: 例如: "scripts": ...
- IdentityServer4【Topic】之定义客户端
Defining Clients 定义客户端 客户端表示哪些可以从你的IdentityServer拿到token的应用. 除了一些可能会变化的细节之外,通常情况下你需要为一个客户端定义如下通用的设置: ...
- python学习笔记(9)--函数
函数定义: def <函数名>(<参数(0个或多个)>): 函数体 return <返回值> 参数有非可选参数,和可选参数,可选参数放在参数列表的最后,可以为可选参 ...