poj 3608 旋转卡壳求两凸包间的最近距离
来源:互联网 发布:泰国贫富差距知乎 编辑:程序博客网 时间:2024/04/27 14:07
旋转卡壳的确很卡人。现在本人学旋转卡壳还在初级阶段。但是这是算法的效率的确很高,所有必需得学会
我想说的是旋转卡壳求凸包的最近点对距离。大体思路如下:
对于给定的点,调整为逆时针方向;
一个P凸包中找纵坐标最小的点,在另一个Q凸包中找纵坐标最大的点;
进行卡壳处理,具体处理应为这样:
在p中纵坐标的最小点与之相邻的下标大一点与Q中纵坐标最大点组成三角形,再与Q中纵坐标最大点相邻的点下标大一的点组成另一个三角形。判断这两个三角形的面积的大小,进行旋转卡壳;如果卡不下去,就求距离,求距离时,分情况来求,可能是点到直线的距离,也可能卡壳的两条线平行,这样就直线间的距离。
求点到直线的距离,还有就是线到线段距离时候,需要处理一下,我觉得对我来说,这是难点。
代码如下,做的时候,叉积一直搞错,得注意...TT....
我想说的是旋转卡壳求凸包的最近点对距离。大体思路如下:
对于给定的点,调整为逆时针方向;
一个P凸包中找纵坐标最小的点,在另一个Q凸包中找纵坐标最大的点;
进行卡壳处理,具体处理应为这样:
在p中纵坐标的最小点与之相邻的下标大一点与Q中纵坐标最大点组成三角形,再与Q中纵坐标最大点相邻的点下标大一的点组成另一个三角形。判断这两个三角形的面积的大小,进行旋转卡壳;如果卡不下去,就求距离,求距离时,分情况来求,可能是点到直线的距离,也可能卡壳的两条线平行,这样就直线间的距离。
求点到直线的距离,还有就是线到线段距离时候,需要处理一下,我觉得对我来说,这是难点。
代码如下,做的时候,叉积一直搞错,得注意...TT....
#include<stdio.h>#include<iostream>#include<math.h>#include<algorithm>using namespace std;#define N 10002#define EPS 1e-10struct point{ double x; double y;}pn[N],pm[N];double dis(point a,point b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}double det(double x1,double y1,double x2,double y2){ return x1*y2-x2*y1;}double cross(point a,point b,point c){ return det(a.x-c.x,a.y-c.y,b.x-c.x,b.y-c.y);}double dot(point a,point b){ return a.x*b.x+a.y*b.y;}double min(double a,double b){ return a>b?b:a;}void adjust(point *p,int n){ for(int i=0;i<n-2;i++) { int res=cross(p[i+1],p[i+2],p[i]); if(res>EPS)return; else if(res<-EPS) { reverse(p,p+n); return; } }}double point_to_seg(point a,point b,point c){ point ab,ac; ab.x=b.x-a.x; ab.y=b.y-a.y; ac.x=c.x-a.x; ac.y=c.y-a.y; double f=dot(ab,ac); if(f<0)return dis(a,c); double f1=dot(ab,ab); if(f>f1)return dis(b,c); f=f/f1; point d; d.x=a.x+ab.x*f; d.y=a.y+ab.y*f; return dis(d,c);}double seg_to_seg(point a1,point b1,point a2,point b2){ return min(min(point_to_seg(a1,b1,a2),point_to_seg(a1,b1,b2)),min(point_to_seg(a2,b2,a1),point_to_seg(a2,b2,b1)));}double rc(point *p1,int n,point *p2,int m){ int s1=0,s2=0; for(int i=0;i<n;i++) { if(p1[i].y-p1[s1].y<-EPS) { s1=i; } } for(int i=0;i<m;i++) { if(p2[i].y-p2[s2].y>EPS) { s2=i; } } p1[n]=p1[0]; p2[m]=p2[0]; double res,ans=1e20; for(int i=0;i<n;i++) { while((res=cross(p2[s2],p1[s1+1],p1[s1])-cross(p2[s2+1],p1[s1+1],p1[s1]))>EPS) { s2=(s2+1)%m; } if(res<-EPS)ans=min(ans,point_to_seg(p1[s1],p1[s1+1],p2[s2])); else ans=min(ans,seg_to_seg(p1[s1],p1[s1+1],p2[s2],p2[s2+1])); s1=(s1+1)%n; } return ans;}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; for(int i=0;i<n;i++) { scanf("%lf%lf",&pn[i].x,&pn[i].y); } for(int i=0;i<m;i++) { scanf("%lf%lf",&pm[i].x,&pm[i].y); } adjust(pn,n); adjust(pm,m); printf("%.5lf\n",sqrt(min(rc(pn,n,pm,m),rc(pm,m,pn,n)))); } return 0;}
- poj 3608 旋转卡壳求两凸包间的最近距离
- poj3608 凸包间最近距离 旋转卡壳
- POJ 3608 两凸包最近距离 旋转卡壳
- 旋转卡壳求凸包间的最短距离 POJ 3608
- POJ 3608 旋转卡壳求解凸包间的最短距离
- 旋转卡壳凸包间最小距离
- poj 3608 Bridge Across Islands 旋转卡壳(两个凸包的最近距离)
- poj3608(旋转卡壳求两凸包间的最短距离)
- POJ 3608 求两凸包的最小距离 (凸包+旋转卡壳)
- POJ 3608 Bridge Across Islands(两个凸包最近距离,旋转卡壳)
- POJ3608(旋转卡壳--求两凸包的最近点对距离)
- POJ3608(旋转卡壳--求两凸包的最近点对距离)
- poj 3608 Bridge Across Islands(旋转卡壳求俩凸包间最小间距)
- poj 3608 (旋转卡壳)
- POJ 3608 Bridge Across Islands(求两凸包间的最小距离)
- poj 3608 Bridge Across Islands(卡壳旋转求两个多边形的最近点对)
- poj 3608 Bridge Across Islands题解(凸包+求两凸包间的最近点对)
- hdu 2823 The widest road (旋转卡壳求两凸包的最近距离)
- Android Service学习之本地服务
- 【dos BAT】关于DOS的批处理学习过程 之二
- CS0433: 类型同时存在于“c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\
- 手把手教你写专利申请书·如何申请专利
- linux 学习笔记
- poj 3608 旋转卡壳求两凸包间的最近距离
- STL find_if
- Jquery主要控件的取值、赋值,包括textbox,button,lable,radio,checkbox,selected
- arm寄存器别名
- Android 自动解锁 KeyguardManager(键盘管理器)
- c语言二维数组与指针
- Gaia项目总结(3)HTML与JS设置
- CF D. Buses
- 编译android 2.3, 出现`GLIBC_2.11' not found