旋转卡壳:cdoj942

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<cmath>
using namespace std;
#define maxn 10000

struct point{
	double x,y;
	point(){
		x=y=0;
	}
	point(double x,double y){
		this->x=x;this->y=y;
	}
	bool operator < (const point & a)const {
		return y<a.y||(y==a.y&&x<a.x);
	}
};
typedef point Vector;

Vector operator+(Vector &a,Vector &b){
	return Vector(a.x+b.x,a.y+b.y);
}
Vector operator-(Vector &a,Vector &b){
	return Vector(a.x-b.x,a.y-b.y);
}
bool operator==(const Vector &a,const Vector &b){
	return fabs(a.x-b.x)==0&&fabs(a.y-b.y)==0;
}
double outer_product(Vector a,Vector b){
	return a.x*b.y-a.y*b.x;
}
double inner_product(Vector a,Vector b){
	return a.x*b.x+a.y*b.y;
}
double Length(Vector A){
	return sqrt(inner_product(A,A));
}

int convex_hull(point * p,int n,point *ch){
	sort(p,p+n);
	int m=0;
	for(int i=0;i<n;i++){
		while(m>1&&outer_product(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0)m--;
		ch[m++]=p[i];
	}
	int k=m;
	for(int i=n-2;i>=0;i--){
		while(m>k&&outer_product(ch[m-1]-ch[m-2],p[i]-ch[m-2])<0)m--;
		ch[m++]=p[i];
	}
	return m-1;
}
//c到线段AB的距离 
double dist(point C,point A,point B){
	if(A==B)return Length(C-A);
	Vector v1=B-A,v2=C-A,v3=B-C;
	if(inner_product(v1,v2)<0)return Length(v2);
	else if(inner_product(v1,v3)<0)return Length(v3);
	else return fabs(outer_product(v1,v2)/Length(v1));
}
double min_4(double a,double b,double c,double d){
	if(b<a)a=b;if(c<a)a=c;if(d<a)a=d;return a;
}
double mindist(point A,point B,point C,point D){
	return min_4(dist(C,A,B),dist(D,A,B),dist(A,C,D),dist(B,C,D));
}
double spin_shell(point *p1,point *p2,int n,int m){
	int minP=0,maxQ=0;
	for(int i=0;i<n;i++){
		if(p1[i].y<p1[minP].y)
			minP=i;
	}
	for(int i=0;i<m;i++){
		if(p2[i].y>p2[maxQ].y)
			maxQ=i;
	}
	int yminP=minP,ymaxQ=maxQ;
	p1[n]=p1[0];p2[m]=p2[0];
	double ans=1e9;

	for(int i=0;i<n;i++){
		while(outer_product(p1[yminP+1]-p1[yminP],p2[ymaxQ+1]-p2[ymaxQ])<0){
			ymaxQ=(ymaxQ+1)%m;
			ans=min(ans,mindist(p1[yminP],p1[yminP+1],p2[ymaxQ],p2[ymaxQ+1]));
		}
			ans=min(ans,mindist(p1[yminP],p1[yminP+1],p2[ymaxQ],p2[ymaxQ+1]));
		yminP=(yminP+1)%n;
	}

	yminP=minP,ymaxQ=maxQ;
	for(int i=0;i<n;i++){
		while(outer_product(p1[yminP+1]-p1[yminP],p2[ymaxQ+1]-p2[ymaxQ])>=0){
			ymaxQ=(ymaxQ+1)%m;
			ans=min(ans,mindist(p1[yminP],p1[yminP+1],p2[ymaxQ],p2[ymaxQ+1]));
		}	
			ans=min(ans,mindist(p1[yminP],p1[yminP+1],p2[ymaxQ],p2[ymaxQ+1]));
		yminP=(yminP+1)%n;
	}
	
	return ans;
}
int N,M;
point P1[maxn+10],P2[maxn+10];
point hu1[maxn+10],hu2[maxn+10];
int main(){
	//freopen("in.txt","r",stdin);
	
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++)scanf("%lf%lf",&P1[i].x,&P1[i].y);
	for(int i=0;i<M;i++)scanf("%lf%lf",&P2[i].x,&P2[i].y);

	int a=convex_hull(P1,N,hu1);
	int b=convex_hull(P2,M,hu2);
	
	printf("%.5f\n",spin_shell(hu1,hu2,a,b));
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值