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));
    	}
    }




  • 相关阅读:
    python批量安装模块 批量导出模块
    java 基础学习1
    linux 命令小记
    nosql数据库-mongodb
    python 列表大小快速比较方法
    nvidia-smi 系列命令,查看gpu ,显存信息
    pipinstaller
    pyinstaller 模块-python文件生成exe可执行文件
    git命令提交到github代码
    subprocess.Popen()
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611240.html
Copyright © 2011-2022 走看看