POJ 3608 求两个凸包之间的最小距离
来源:互联网 发布:网络辣条是什么意思 编辑:程序博客网 时间:2024/06/01 21:48
题解 :
首先我们要知道一种遍历所有对踵点的算法 : 就是用旋转卡壳加上叉积判断是否旋转的一种算法。
剩下的就是求对踵点了
因为我们不难发现,对于两个凸包来说,他们之间的最小距离肯定在对踵点上。然后我们就可以去便利所有的对踵点这样同时保留最小距离这样就可以了。注意求一个线段到另一条线段的最小距离应该用点积去算就好了
还有我们需要深入理解关于旋转卡壳的几个有关的概念
1. 支撑线
2. 对踵点
3. 什么时候卡壳旋转
4. 旋转卡壳
只有这些理解到位以后才可以做这道题 注意对于多个凸包而言,我们需要每一个都去做一遍旋转卡壳。\
#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 1e4 + 10;const double eps = 1e-8;const double INF = 1e88;struct node { double x,y;}p[maxn],q[maxn];node init;int sgn (double x) { if (fabs (x) < eps) return 0; return x > 0 ? 1 : -1;}double cross (double x1,double y1,double x2,double y2) { return x1 * y2 - x2 * y1;}double muit (double x1,double y1,double x2,double y2) { return x1 * x2 + y1 * y2;}double dist (node a,node b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}bool cmp (const node a,const node b) { int sg = sgn (cross (a.x - init.x,a.y - init.y,b.x - init.x,b.y - init.y)); if (sg == 0) return dist (a,init) < dist (b,init); return sg > 0;}double dist (node a,node b,node c) { if (dist (a,b) < eps) return dist (a,c); if (sgn(muit(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y)) < 0) return dist (a,c); if (sgn(muit(a.x - b.x, a.y - b.y, c.x - b.x, c.y - b.y) < 0)) return dist (b,c); return fabs (cross(c.x - a.x, c.y - a.y, b.x - a.x, b.y - a.y) / dist (a,b));}double ansdist (node a,node b,node c,node d) { return min (min (dist (a,b,c),dist (a,b,d)),min(dist (c,d,a),dist (c,d,b)));}void mysort (node a[],int n) { for (int i = 1;i <= n; ++ i) { if (a[i].y < a[1].y || (a[i].y == a[1].y && a[i].x < a[1].x)) { swap (a[1],a[i]); } } init = a[1];// printf ("%.3f %.3f\n",init.x,init.y); sort (a + 1,a + 1 + n,cmp);}double rotating (node p[],node q[],int n,int m) { int miny = 1,maxy = 1; double mx = 0; p[n + 1] = p[1]; q[m + 1] = q[1]; for (int i = 1;i <= m; ++ i) { if (q[i].y > mx) { mx = q[i].y; maxy = i; } } double ans = dist (p[miny],q[maxy]); for (int i = 1;i <= n; ++ i) { while ((cross (q[maxy + 1].x - p[miny + 1].x,q[maxy + 1].y - p[miny + 1].y,p[miny].x - p[miny + 1].x,p[miny].y - p[miny + 1].y)-cross (q[maxy].x - p[miny + 1].x,q[maxy].y - p[miny + 1].y,p[miny].x - p[miny + 1].x,p[miny].y - p[miny + 1].y)) > eps) { maxy = maxy % m + 1; } ans = min (ans,ansdist (p[miny],p[miny + 1],q[maxy],q[maxy + 1])); miny = miny % n + 1; } return ans;}int main () { int n,m; while (scanf ("%d%d",&n,&m) && n) { for (int i = 1;i <= n; ++ i) { scanf ("%lf%lf",&p[i].x,&p[i].y); } for (int i = 1;i <= m; ++ i) { scanf ("%lf%lf",&q[i].x,&q[i].y); } mysort(p, n); mysort(q, m);// for (int i = 1;i <= m; ++ i) {// printf ("%.3f %.3f\n",q[i].x,q[i].y);// } printf ("%.5f\n",min (rotating(p, q, n, m),rotating(q, p, m, n))); } return 0;}
阅读全文
0 0
- POJ 3608 求两个凸包之间的最小距离
- POJ 3608 求两凸包的最小距离 (凸包+旋转卡壳)
- 用于求两个向量之间的距离
- PHP【求两个经纬度之间的距离】
- poj 3608 Bridge Across Islands 旋转卡壳(两个凸包的最近距离)
- LeetCode219 查找相等两个数之间的最小距离
- 【谷歌面试题】求数组中两个元素的最小距离
- 求数组中两个元素的最小距离
- 求数组中两个元素的最小距离
- 用最小编辑距离求两个字符串的不同
- 求数组中两个字符串的最小距离 Python 版
- 求算两个字符串之间的编辑距离
- HDU1007(求最近两个点之间的距离)
- 求两个已知经纬度之间的距离,单位为米
- Kendall tau距离:求两个排列之间的逆序数
- 求算两个字符串之间的编辑距离
- 求两个整数之间的汉明距离---Salem
- Kendall tau距离:求两个排列之间的逆序数
- 浅析浅拷贝与深拷贝
- 训练总结 10.1
- java基础-锁
- Quartz定时任务框架
- 概率基础
- POJ 3608 求两个凸包之间的最小距离
- leetcode 7. Reverse Integer(C语言,翻转一个整数,判断是否溢出)19
- bmp字节对齐公式
- document 对象的集合对象以及为什么js有时候需要在body中
- 简要说明python pandas中groupby,agg等的用法
- 排序算法之冒泡排序
- Error in `appstreamcli': double free or corruption (fasttop): 0x0000000002122000
- Java——map详细介绍
- 【分享】windows通信端口初始化失败