poj3608_Bridge Across Islands_旋转卡壳&&点到线段的距离
2017-12-30 18:22
447 查看
题意
给出两个凸包,现要用一条线段连接这两个凸包,求这条线段的最小长度。思路
从第一个凸包y值最小的那个点,和第二个凸包y值最大的那个点出发,旋转卡壳。链接
http://poj.org/problem?id=3608代码
#include<cstdio> #include<algorithm> #include<cmath> using namespace std; const double eps = 1e-8; const int maxn = 10101; const double inf = 1e11; struct P{ double x, y; P(){} P(double x, double y): x(x), y(y){} void read(){ scanf("%lf %lf", &x, &y); } P operator -(P p){ return P(x - p.x, y - p.y); } P operator *(double p){ return P(x * p, y * p); } double dot(P p){ return x * p.x + y * p.y; } double det(P p){ return x * p.y - y * p.x; } }; int n, m; P A[maxn], B[maxn]; //将两个凸包分别排成逆时针顺序 void AntiClockWise(P *A, int n){ for(int i = 0; i < n - 2; ++i){ if((A[i+1] - A[i]).det(A[i+2] - A[i]) > eps) return; else if((A[i+1] - A[i]).det(A[i+2] - A[i]) < -eps){ reverse(A, A + n); return; } } } //计算 a b 两点之间的距离 double dist(P a, P b){ double x = a.x - b.x, y = a.y - b.y; return sqrt(x * x + y * y); } //计算点 a 到线段 bc 的距离 double distPL(P a, P b, P c){ if(dist(b, c) < eps) return dist(a, c); if((a - b).dot(c - b) < -eps) return dist(a, b); if((a - c).dot(b - c) < -eps) return dist(a, c); return fabs((a - c).det(b - c) / dist(b, c)); } //计算线段 ab 和 cd 之间的最小距离 double distLL(P a, P b, P c, P d){ return min(min(distPL(c, a, b), distPL(d, a, b)), min(distPL(a, c, d), distPL(b, c, d))); } double solve(){ int it0 = 0, it1 = 0; for(int i = 0; i < n; ++i){//找到第一个凸包y值最小的点 if(A[i].y < A[it0].y) it0 = i; } for(int i = 0; i < m; ++i){//找到第二个凸包y值最大的点 if(B[i].y > B[it1].y) it1 = i; } A = A[0], B[m] = B[0];//将凸包首尾相接,方便旋转 double res = inf; for(int i = 0 bbf4 ; i < n; ++i){ while((B[it1] - A[it0]).det(A[it0+1] - A[it0]) - (B[it1 + 1] - A[it0]).det(A[it0+1] - A[it0]) > eps) it1 = (it1 + 1) % m; res = min(res, distLL(A[it0], A[it0+1], B[it1], B[it1+1])); it0 = (it0 + 1) % n; } return res; } int main(){ while(scanf("%d %d", &n, &m) == 2){ if(n == 0 && m == 0) break; for(int i = 0; i < n; ++i){ A[i].read(); } for(int i = 0; i < m; ++i){ B[i].read(); } AntiClockWise(A, n); AntiClockWise(B, m); printf("%.5f\n", solve()); } return 0; }
相关文章推荐
- [POJ3608]Bridge Across Islands(计算几何-旋转卡壳-凸多边形间最小距离)
- 【旋转卡壳】poj3608 Bridge Across Islands
- POJ 3608 Bridge Across Islands(两个凸包最近距离,旋转卡壳)
- POJ 3608 Bridge Across Islands(旋转卡壳 求不相交凸包之间的最短距离)
- POJ 3608 Bridge Across Islands(旋转卡壳,两凸包最短距离)
- poj 3608 Bridge Across Islands 旋转卡壳(两个凸包的最近距离)
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
- poj 3608 Bridge Across Islands, 旋转卡壳求凸多边形间最小距离
- poj 3608 Bridge Across Islands(旋转卡壳求凸包最短距离)
- Bridge Across Islands POJ - 3608 凸多边形间最小距离/旋转卡壳
- 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
- Bridge Across Islands----POJ_3608----求两凸包最近距离----旋转卡壳
- POJ 3608 Bridge Across Islands(旋转卡壳求凸多边形最短距离)
- poj 3608 Bridge Across Islands(旋转卡壳)
- poj 3608 Bridge Across Islands(卡壳旋转求两个多边形的最近点对)
- poj 3608 Bridge Across Islands(旋转卡壳求俩凸包间最小间距)
- POJ 3608 Bridge Across Islands (旋转卡壳)
- POJ 3608 Bridge Across Islands [旋转卡壳]
- POJ 3608 Bridge Across Islands(旋转卡壳)
- poj3608 Bridge Across Islands (旋转卡壳之两凸包最短距)