Bridge Across Islands POJ - 3608 凸多边形间最小距离/旋转卡壳
旋转的部分始终感觉有点别扭。。后来发现是因为叉积顺序为负。。
所以让三角形面积逐渐变大实际上就是让三角形面积变小(绝对值意义上的),这样就是让高变小了。。
至于为什么要选最下和最上。。应该是为了满足两条线始终可以生成所有多边形间的对踵点对吧?
//#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; const double pi=acos(-1.0); #define ll long long #define pb push_back #define sqr(a) ((a)*(a)) #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)) const double eps=1e-10; const int maxn=5e4+56; const int inf=0x3f3f3f3f; struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} Point operator -(const Point &p){return Point(x-p.x,y-p.y);} bool operator<(const Point &a)const{ if(x!=a.x)return x<a.x; else return y<a.y; } double dot(const Point&p){return x*p.x+y*p.y;} double det(const Point&p){return x*p.y-y*p.x;} }; Point P[maxn],Q[maxn]; //AB与AC的叉积,正表示C在向量AB的逆时针方向 double cross(Point A,Point B,Point C){ return (B-A).det(C-A); } //AB与AC的点积,0则垂直 double multi(Point A,Point B,Point C){ return (B-A).dot(C-A); } void anticlockwise_sort(Point *p,int N){ for(int i=0;i<N-2;i++){ double tmp=cross(p[i],p[i+1],p[i+2]); if(tmp>eps)return; else if(tmp<-eps){ reverse(p,p+N);return; } } } //C到线段AB的距离 double point_to_line(Point A,Point B,Point C){ if(dis(A,B)<eps)return dis(B,C); if(multi(A,B,C)<-eps)return dis(A,C); if(multi(B,A,C)<-eps)return dis(B,C); return fabs(cross(A,B,C)/dis(A,B)); //面积 } //两线段AB到CD的距离 double line_to_line(Point A,Point B,Point C,Point D){ return min(min(point_to_line(A,B,C),point_to_line(A,B,D)), min(point_to_line(C,D,A),point_to_line(C,D,B)) ); } //两凸包求距 // double solve(Point *P,Point *Q,int n,int m){ int yminP=0,ymaxQ=0; for(int i=0;i<n;i++)if(P[i].y<P[yminP].y)yminP=i; for(int i=0;i<m;i++)if(Q[i].y>Q[ymaxQ].y)ymaxQ=i; P[n]=P[0];Q[m]=Q[0]; double arg,ans=inf; for(int i=0;i<n;i++){ //枚举p上的点 while(arg=(cross(P[yminP+1],Q[ymaxQ+1],P[yminP]) - cross(P[yminP+1],Q[ymaxQ],P[yminP]))>eps){ /* cout<<"here"<<endl; cout<<cross(P[yminP+1],Q[ymaxQ+1],P[yminP])<<endl; cout<<cross(P[yminP+1],Q[ymaxQ],P[yminP])<<endl; cout<<P[yminP].x<<" "<<Q[ymaxQ].x<<"ww"<<endl; */ ymaxQ=(ymaxQ+1)%m; } ans=min(ans,line_to_line(P[yminP],P[yminP+1],Q[ymaxQ],Q[ymaxQ+1])); yminP=(yminP+1)%n; } return ans; } int main(){ int N,M; while(~scanf("%d%d",&N,&M)&&N){ for(int i=0;i<N;i++){ scanf("%lf%lf",&P[i].x,&P[i].y); } for(int i=0;i<M;i++){ scanf("%lf%lf",&Q[i].x,&Q[i].y); } anticlockwise_sort(P,N);anticlockwise_sort(Q,M); printf("%.5lf\n",solve(P,Q,N,M)); } }