zoukankan      html  css  js  c++  java
  • bzoj 1069 凸包+旋转卡壳

    题目大意

    在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
    的多边形面积最大。

    分析

    枚举对角线的一个端点
    另一个端点开始转
    转的时候求出对角线左边面积最大的三角形,右边面积最大的三角形
    三角形面积(=)对角线长度(*)
    (=)两条平行线间任意两点距离
    过对角线做两条平行线,对着凸包夹一夹
    可以发现这实际上就是一个旋转卡壳
    (O(n^2))

    solution

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    typedef long double db ;
    using namespace std;
    const int M=2007;
    
    struct pt{
    	db x,y;
    	pt(db xx=0.0,db yy=0.0){x=xx;y=yy;}
    }p[M],s[M];
    pt operator -(pt x,pt y){return pt(x.x-y.x,x.y-y.y);}
    pt operator +(pt x,pt y){return pt(x.x+y.x,x.y+y.y);}
    bool operator <(pt x,pt y){if(x.y!=y.y)return x.y<y.y; return x.x<y.x;}
    db cross(pt x,pt y){
    	return x.x*y.y-x.y*y.x;
    }
    db dot(pt x,pt y){
    	return x.x*y.x+x.y*y.y;
    }
    db area(pt x,pt y,pt z){
    	return cross(y-x,z-x);
    }
    db length(pt x){
    	return sqrt(dot(x,x));
    };
    db shadow(pt x,pt to){
    	return dot(x,to)/length(to);
    }
    
    bool cmp(pt x,pt y){//ÄæʱÕ뼫½ÇÅÅÐò 
    	db tp=area(p[1],x,y);
    	if(tp==0) return length(x-p[1])<length(y-p[1]);
    	return tp>0;	
    }
    
    int n;
    
    int tot;
    
    void convex(){
    	int ii=1,i;
    	for(i=1;i<=n;i++) if(p[i]<p[ii]) ii=i;
    	swap(p[1],p[ii]);
    	sort(p+2,p+n+1,cmp);
    	
    	s[tot=1]=p[1];
    	for(i=2;i<=n;i++){
    		while(tot>1&&area(s[tot-1],s[tot],p[i])<=0) tot--;//  <=  
    		s[++tot]=p[i];
    	} 
    }
    
    int main(){
    	int i,j,k,p1,p2;
    	db x,y;
    	scanf("%d",&n);
     	for(i=1;i<=n;i++){
     		scanf("%Lf%Lf",&x,&y);
     		p[i]=pt(x,y);
    	}
    	
    	convex();
    	
    	db ans=0;
    	for(i=1;i<tot;i++){
    		p1=i,p2=i+1;
    		for(j=i+1;j<=tot;j++){
    			while(area(s[i],s[p1],s[j])<area(s[i],s[p1%tot+1],s[j])) p1=p1%tot+1;
    			while(area(s[i],s[j],s[p2])<area(s[i],s[j],s[p2%tot+1])) p2=p2%tot+1;
    			ans=max(ans,area(s[i],s[p1],s[j])+area(s[i],s[j],s[p2]));
    		}
    	}
    	
    	printf("%.3Lf
    ",ans/2.0);
    
    	return 0;
    }
    
  • 相关阅读:
    lucene中创建索引库
    商城后台上架商品列表查询的书写全过程
    Linux命令英文全称
    商品品牌分页、过滤、排序查询的完成流程
    axios使用步骤详解(附代码)
    使用CORS处理跨域请求
    npm 是干什么的?
    Mybatis通用Mapper介绍和使用
    FastDFS的理解和分析
    CDN服务的含义
  • 原文地址:https://www.cnblogs.com/acha/p/6429336.html
Copyright © 2011-2022 走看看