Bridge Across Islands POJ

旋转的部分始终感觉有点别扭。。后来发现是因为叉积顺序为负。。

所以让三角形面积逐渐变大实际上就是让三角形面积变小(绝对值意义上的),这样就是让高变小了。。

至于为什么要选最下和最上。。应该是为了满足两条线始终可以生成所有多边形间的对踵点对吧?

//#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
",solve(P,Q,N,M));
	}
}




原文地址:https://www.cnblogs.com/Drenight/p/8611240.html