Bridge Across Islands
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11196   Accepted: 3292   Special Judge

Description

Thousands of thousands years ago there was a small kingdom located in the middle of the Pacific Ocean. The territory of the kingdom consists two separated islands. Due to the impact of the ocean current, the shapes of both the islands became convex polygons. The king of the kingdom wanted to establish a bridge to connect the two islands. To minimize the cost, the king asked you, the bishop, to find the minimal distance between the boundaries of the two islands.

Input

The input consists of several test cases.
Each test case begins with two integers NM. (3 ≤ NM ≤ 10000)
Each of the next N lines contains a pair of coordinates, which describes the position of a vertex in one convex polygon.
Each of the next M lines contains a pair of coordinates, which describes the position of a vertex in the other convex polygon.
A line with N = M = 0 indicates the end of input.
The coordinates are within the range [-10000, 10000].

Output

For each test case output the minimal distance. An error within 0.001 is acceptable.

Sample Input

4 4
0.00000 0.00000
0.00000 1.00000
1.00000 1.00000
1.00000 0.00000
2.00000 0.00000
2.00000 1.00000
3.00000 1.00000
3.00000 0.00000
0 0

Sample Output

1.00000

题意:求两个凸包之间的最近距离
思路:找到第一个凸包的右下角的顶点和第二个凸包左上角的顶点,第一个凸包从右下角顶点开始与逆时针方向的下一个顶点作直线,暂且固定这条直线,第二个凸包的左上角的顶点也与逆时针方向下一个顶点结合作直线,判断两条直线方向,若第二条直线需要逆时针转动才能转到第一条直线的方向,那么第二条直线继续逆时针旋转,即
逆时针方向找到接下来一个顶点,这个顶点与上一个顶点形成新的直线,直到当前形成的直线与第一条直线平行或者需要顺时针旋转才能转到第一条直线的方向为止停止转动,并计算当前的两条直线所在的线段的距离,更新最短距离。之后第一条直线逆时针转动到下一个方向后继续固定,重复上述算法。。

AC代码:
Source Code

Problem:         User: ach11090913
Memory: 980K Time: 172MS
Language: C++ Result: Accepted
Source Code
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
#define EPS 1e-10
#define INF 0x3f3f3f3f
const int N_MAX = *+;
double add(double a,double b) {
if (abs(a + b) < EPS*(abs(a) + abs(b)))return ;
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 *(P p) {
return P(x*p.x, y*p.y);
}
bool operator <(const P& p)const {
if (x != p.x)return x < p.x;
else return y < p.y;
}
double dot(P p) {
return add(x*p.x,y*p.y);
}
double det(P p) {
return add(x*p.y, -y*p.x);
}
double norm() {
return x*x + y*y;
}
double abs() {
return sqrt(norm());
} };
bool cmp_y1(const P&p,const P&q) {
if (p.y != q.y)
return p.y < q.y;
return p.x > q.x;
} struct Segment {
P p1, p2;
Segment(P p1=P(),P p2=P()):p1(p1),p2(p2) {}
};
typedef Segment Line;
typedef vector<P>Polygon; inline double cross(P A, P B, P C)
{
return (B - A).det(C - A);
} double getDistanceLP(Line l,P p) {
return fabs((l.p2 - l.p1).det(p - l.p1)) / ((l.p2 - l.p1).abs());
} double getDistanceSP(Segment s,P p) {
if ((s.p2 - s.p1).dot(p - s.p1) < 0.0)return (p - s.p1).abs();
if ((s.p1 - s.p2).dot(p - s.p2) < 0.0)return (p - s.p2).abs();
return getDistanceLP(s, p);
} double getDistance(Segment s1,Segment s2) {
return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
} Polygon po1, po2;
int N, M; vector<P> judge_clockwise(vector<P>p) {
for (int i = ; i < p.size()-;i++) {
//double tmp = (p[i + 1] - p[i]).det(p[i + 2] - p[i + 1]);
double tmp = cross(p[i], p[i + ], p[i + ]);
if (tmp > EPS)return p;
else if (tmp < -EPS) {
reverse(p.begin(), p.end());
return p;
}
}
return p;
} double solve() {
int i = , j = ;
for (int k = ; k < N;k++) {
if (!cmp_y1(po1[i], po1[k]))i = k;//i为凸包右下角
}
for (int k = ; k < M; k++) {
if (cmp_y1(po2[j], po2[k]))j = k;//j为凸包左上角
}
double res = INF;
for (int k = ; k< N;k++) {
while ((po1[i] - po1[(i + ) % N]).det(po2[(j + ) % M] - po2[j]) < ) j = (j + ) % M;
Segment s1, s2;
s1.p1 = po1[i], s1.p2 = po1[(i + ) % N],s2.p1=po2[j],s2.p2=po2[(j+)%M];
res = min(res, getDistance(s1, s2));
//cout << s1.p1.x << " " << s1.p1.y << " " << s1.p2.x << " " << s1.p2.y <<" " << s2.p1.x << " " << s2.p1.y << " " << s2.p2.x <<" "<< s2.p2.y << endl;
i = (i + ) % N;
}
return res;
} int main() { while (scanf("%d%d",&N,&M)&&N) {
po1.clear();
po2.clear();
for (int i = ; i < N;i++) {
double x, y;
scanf("%lf%lf",&x,&y);
po1.push_back(P(x,y));
}
po1=judge_clockwise(po1);
for (int i = ; i < M;i++) {
double x, y;
scanf("%lf%lf", &x, &y);
po2.push_back(P(x,y));
}
po2=judge_clockwise(po2);
printf("%.5f\n",solve());
}
return ;
}

poj 3068 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

    题链: http://poj.org/problem?id=3608 题解: 计算几何,求两个凸包间的最小距离,旋转卡壳 两个凸包间的距离,无非下面三种情况: 所以可以基于旋转卡壳的思想,去求最小距离 ...

  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【旋转卡壳】及一些有趣现象

    给两个凸包,求这两个凸包间最短距离 旋转卡壳的基础题 因为是初学旋转卡壳,所以找了别人的代码进行观摩..然而发现很有意思的现象 比如说这个代码(只截取了关键部分) double solve(Point ...

  9. poj 3608 Bridge Across Islands 两凸包间最近距离

    /** 旋转卡壳,, **/ #include <iostream> #include <algorithm> #include <cmath> #include ...

随机推荐

  1. HTML DOM Frame 的 src

    定义和用法 src 属性可设置或返回应当被载入框架中的文档的 URL. 该属性只是 HTML 的 <frame> 标记的一个对应,并不是 Window.location 这样的 Locat ...

  2. GCD之dispatch queue

    GCD之dispatch queue iOS中多线程编程工具主要有: NSThread NSOperation GCD 这三种方法都简单易用,各有千秋.但无疑GCD是最有诱惑力的,因为其本身是appl ...

  3. iOS小技巧–用runtime 解决UIButton 重复点击问题

    什么是这个问题 我们的按钮是点击一次响应一次, 即使频繁的点击也不会出问题, 可是某些场景下还偏偏就是会出问题. 通常是如何解决 我们通常会在按钮点击的时候设置这个按钮不可点击. 等待0.xS的延时后 ...

  4. ios sinaweibo 客户端(一)

    上一篇sina微博Demo已经完成的认证,下面就开始进入微博相关内容的加载及显示.其实主要的工作就是调用微博API 加载相关的json数据,然后进行解析,然后在界面中进行组织好在tableview中进 ...

  5. NSURL初始化失败

    服务端给返回的网页加载不出来,仔细一看,url是空的!!为什么呢. 示例: NSString *urlStr = @"http://服务器返回带有汉字的url字符串.com"; N ...

  6. vector总结(更新中。。。)

    vector中这两个属性很容易弄混淆. size是当前vector容器真实占用的大小,也就是容器当前拥有多少个容器. capacity是指在发生realloc前能允许的最大元素数,即预分配的内存空间. ...

  7. java中类与对象的概念(2013-05-04-bd 写的日志迁移

    1:类是抽象的,概念的,代表一类事物,比如人类.猫类.. 2:对象是具体的,实际的,代表一个具体的事物 3:类是对象的模板,对象是类的一个个体,实例 创建对象的两种方法: 1.先声明在创建 对象声明: ...

  8. manjaro linux没有ll等命令的解决办法

    编辑~/.bashrc, 添加alias 如下 vim ~/.bashrc设置别名. 添加如下行 alias ll='ls -alF' alias la='ls -A' alias vi='vim' ...

  9. selenium +python web自动化测试环境搭建

    基础框架搭建 1.安装python 2.安装selenium cmd输入pip install selenium 问题:在python中输入from selenium import webdriver ...

  10. 简单了解hash

    hash,译为散列或哈希.就是把任意长度的输入(可变类型除外)经过hash算法,输出成固定长度的输出,该输出就是hash值.哈希值比原有的输出占用空间要小,但是不同的输出可能会hash出一样的值,所以 ...