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. c++文件偏移

    #include <iostream> #include <fstream> #include <cassert> using namespace std; int ...

  2. 采用maven 对tomcat 进行自动部署

    在工作过程中经常会遇到项目频繁发不到额过程,而且在这个过程中会一直进行一些简单但是繁琐的重复性工程 1.打war 包 2.停掉tomcat 3.copy war 包 4.启动tomcat 听说mave ...

  3. Search and Replace -freecodecamp算法题目

    Search and Replace 1.要求 使用给定的参数对句子执行一次查找和替换,然后返回新句子. 第一个参数是将要对其执行查找和替换的句子. 第二个参数是将被替换掉的单词(替换前的单词). 第 ...

  4. 【转】浅谈对主成分分析(PCA)算法的理解

    以前对PCA算法有过一段时间的研究,但没整理成文章,最近项目又打算用到PCA算法,故趁热打铁整理下PCA算法的知识.本文观点旨在抛砖引玉,不是权威,更不能尽信,只是本人的一点体会. 主成分分析(PCA ...

  5. new和delete的动态分配。

    c++对象模型 视频的实际操作  note: 1.虚函数有虚指针,所以是4,不管有几个虚函数, 都只有一个vptr来存放调用的虚函数的地址. 2.子类的内存是父类内存的加自己的数据内存. 3.clas ...

  6. 使用apache benchmark(ab) 测试报错: apr_socket_recv: Connection timed out (110)

    使用ab( apache benchmark )测试的时候,使用如下命令: ab -n 15000 -c 200   http://localhost/abc/abc.php 执行操作一定条数,或连续 ...

  7. centos里没有pip命令怎么办?

    刚刚入门python的嘛,然后这个centos也是不是那么熟悉!! pip在centos也没有,所以网上找来资料,3条语句就搞定啦! 1.查看是否安装依赖包,没安装先安装: yum install e ...

  8. destoon ip接口失效修改 修改后偶尔会加载很慢

    因为百度ip转换增加了密匙验证,所以导致之前的接口无法再转换ip地址的信息,修复方法如下:打开include\cloud.func.php文件搜索: function iplookup($ip) { ...

  9. 01 Django基础知识

    相关概念 软件框架 一个公司是由公司中的各部部门来组成的,每一个部门拥有特定的职能,部门与部门之间通过相互的配合来完成让公司运转起来. 一个软件框架是由其中各个软件模块组成的,每一个模块都有特定的功能 ...

  10. how to setting a i2c driver

    How to instantiate I2C devices============================== Unlike PCI or USB devices, I2C devices ...