zoukankan      html  css  js  c++  java
  • 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));
    	}
    }




  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611240.html
Copyright © 2011-2022 走看看