POJ3608
计算两个凸包之间的最小距离,旋转卡壳法详解在旋转卡壳的用法之计算两个凸 包上的最近距离
#include <iostream>
#include<cstdio>
#include<string.h>
#include<cmath>
using namespace std;
const double eps=1e-10;
const double INF=1e10;
struct point
{
double x,y;
point (double a=0,double b=0)
{
x=a;
y=b;
}
};
double min_val(double a,double b)
{
return a>b?b:a;
}
int dcmp(double a)
{
if(fabs(a)<eps)return 0;
else return a>0?1:-1;
}
point operator -(point a,point b){ return point (a.x-b.x,a.y-b.y); }
bool operator ==(const point &a,const point &b)
{
return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
void readdate(point a[],int n,point b[],int m)
{
int i;
for(i=0;i<n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
for(i=0;i<m;i++)
scanf("%lf%lf",&b[i].x,&b[i].y);
}
void change(point a[],int b)
{
int i;
point temp;
for(i=0;i<b/2;i++)
{
temp=a[i];
a[i]=a[b-1-i];
a[b-1-i]=temp;
}
}
void work(point p[],int n,point q[],int m)
{
int i;
for(i=0;i<n-2;i++)
if(dcmp(cross(p[i+1]-p[i],p[i+2]-p[i])>0)) break;
else if(dcmp(cross(p[i+1]-p[i],p[i+2]-p[i])<0))
{
change(p,n);
break;
}
for(i=0;i<m-2;i++)
if(dcmp(cross(q[i+1]-q[i],q[i+2]-q[i])>0))break;
else if(dcmp(cross(q[i+1]-q[i],q[i+2]-q[i])<0))
{
change(q,m);
break;
}
}
double Dot(point A,point B){return A.x*B.x+A.y*B.y;}
double Length(point A){return sqrt(Dot(A,A));}
double dist(point a,point b,point p)
{
if(a==b) return Length(p-a);
point v1=b-a,v2=p-a,v3=p-b;
if(dcmp(Dot(v1,v2))<0)return Length(v2);
if(dcmp(Dot(v1,v3))>0)return Length(v3);
return fabs(cross(v1,v2))/Length(v1); }
double Mid(point a1,point a2,point b1,point b2)
{
return min_val(min_val(dist(a1,a2,b1),dist(a1,a2,b2)),
min_val(dist(b1,b2,a1),dist(b1,b2,a2)));
}
double solve(point P[],int n,point Q[],int m)
{
double ans=INF,temp;
int i,minP=0,maxQ=0;
for(i=0;i<n;i++)
if(P[i].y<P[minP].y)
minP=i;
for(i=0;i<m;i++)
if(Q[i].y>Q[maxQ].y)
maxQ=i;
Q[m]=Q[0];
P[n]=P[0];
for(i=0;i<n;i++)
{
while((temp=cross(Q[maxQ+1]-P[minP+1],P[minP]-P[minP+1])
-cross(Q[maxQ]-P[minP+1],P[minP]-P[minP+1]))>eps)
maxQ=(maxQ+1)%m;
if(temp<-eps)
ans=min_val(ans,dist(P[minP],P[minP+1],Q[maxQ]));
else ans=min_val(ans,Mid(P[minP],P[minP+1],Q[maxQ],Q[maxQ+1]));
minP=(minP+1)%n;
}
return ans;
}
int main()
{
point p[10005],q[10005];
int n,m;
double a,b;
while(scanf("%d%d",&n,&m)==2)
{
if(m==0&&n==0)break;
readdate(p,n,q,m);
work(p,n,q,m);
a=solve(p,n,q,m);
b=solve(q,m,p,n);
printf("%.5lf\n",min_val(a,b));
}
return 0;
}
POJ3608的更多相关文章
- 【poj3608】 Bridge Across Islands
http://poj.org/problem?id=3608 (题目链接) 题意 求两凸包间最短距离 Solution 难写难调,旋转卡壳,还真是卡死我了. 先分别选出两凸包最上点和最下点,从这两点开 ...
- 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...
- POJ3608(旋转卡壳--求两凸包的最近点对距离)
题目:Bridge Across Islands 分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696 考虑如下的算法, 算法的 ...
- poj3608 Bridge Across Islands
地址:http://poj.org/problem?id=3608 题目: Bridge Across Islands Time Limit: 1000MS Memory Limit: 65536 ...
- 【旋转卡壳】poj3608 Bridge Across Islands
给你俩凸包,问你它们的最短距离. 咋做就不讲了,经典题,网上一片题解. 把凸包上的点逆时针排序.可以取它们的平均点,然后作极角排序. 旋转卡壳其实是个很模板化的东西…… 先初始化分别在凸包P和Q上取哪 ...
- 旋转卡壳求两个凸包最近距离poj3608
#include <iostream> #include <cmath> #include <vector> #include <string.h> # ...
随机推荐
- 严版数据结构题集2.13 & 2.14
1.试写一算法在带头结点的单链表结构上实现线性表操作Locate(L,x) 2.试写一算法在带头结点的单链表结构上实现线性表操作Length(L) #include<stdio.h> #i ...
- SIM900A基站定位调试笔记 -转
第1步:ATE1 握手并设置回显 第2步:AT+CGMR 查看SIM900的版本信号 第3步:AT+CSQ 查看信号质量 第4步:AT+CREG? 查看GSM是否注册成功 第5步:AT+CGREG? ...
- thinkphp---设置路由
在做一个项目,在项目完成之后,配置一下路由,让URL更容易美观. 下面是具体的配置: Common / Conf / config.php // 路由处理 'URL_HTML_SUFFIX'=> ...
- vue之单表输入绑定
vue的核心:声明式的指令和数据的双向绑定. 那么声明式的指令,已经给大家介绍完了.接下来我们来研究一下什么是数据的双向绑定? 另外,大家一定要知道vue的设计模式:MVVM M是Model的简写,V ...
- [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之三 时间和顺序
这是阅读 http://book.mixu.net/distsys/time.html 的笔记,是该系列的第三章. 为什么时间和顺序很重要呢?为什么我们关系事件A发生在事件B之前? 因为分布式系统要解 ...
- [LintCode] Find the Missing Number 寻找丢失的数字
Given an array contains N numbers of 0 .. N, find which number doesn't exist in the array. Example G ...
- java 多线程研究:锁的概念
java多线程:锁 java的多线程中的锁是干嘛的呢?在网上找了很多博客,大都是很专业的语言,让我一时间摸不着头脑.下面分三个部分来总结多线程中的锁的概念. 一,基础概念: 多线程在运行的时候可能会遇 ...
- sqoop学习笔记
#################################################################################################### ...
- 2018/04/16 PHP 设计模式之工厂模式
学习设计模式一定要知道它是为了什么而产生的,凡事一定有原因. 站在巨人的肩膀上学习,推荐两篇文章 什么是php工厂模式?为何要用php工厂模式? php工厂模式的使用实例总结 PHP设计模式之工厂模式 ...
- 使用QT设计师-信号和槽signal-slot(第一弹)
自定义信号和槽的步骤: 1.定义信号---signal1 = pyqtSignal() 2.定义槽信号---def setSlot(self): 3.连接信号和槽函数---signal1.connec ...