zoukankan      html  css  js  c++  java
  • Luogu-4196 [CQOI2006]凸多边形

    凸多边形的面积就相当于半平面交

    求几个凸多边形面积交就相当于一堆半平面一起求交

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1e3+100;
    struct Point{
        double x,y;
        Point(double xx=0,double yy=0){
            x=xx,y=yy;
        }
    }a[maxn],p[maxn];
    struct Vector{
        double x,y;
        Vector(double xx=0,double yy=0){
            x=xx,y=yy;
        }
    };
    struct Line{
        Point p;
        Vector v;
        double ang;
        Line(Point a=Point(),Vector b=Vector()){
            p=a,v=b;
            ang=atan2(v.y,v.x);
        }
    }q[maxn],b[maxn];
    int dcmp(double x){return fabs(x)<1e-9?0:(x>0?1:-1);}
    Vector operator - (Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}
    Point operator + (Point a,Vector b){return Point(a.x+b.x,a.y+b.y);}
    Vector operator * (double p,Vector a){return Vector(a.x*p,a.y*p);}
    double operator * (Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    double operator * (Point a,Point b){return a.x*b.y-a.y*b.x;}
    bool operator < (Line x,Line y){return dcmp(x.ang-y.ang)==0?(dcmp(x.v*(y.p-x.p))>0):(x.ang<y.ang);}
    Point glt(Line x,Line y){Vector v=x.p-y.p; return x.p+(y.v*v)/(x.v*y.v)*x.v;}
    bool onright(Line a,Line b,Line t){Point p=glt(a,b); return dcmp(t.v*(p-t.p))<0;}
    void bpm(Line *b,int &n,Point *p){
        sort(b+1,b+n+1);
        int l=0,r=1,tot=0;
        for(int i=1;i<=n;i++){
            if(b[i].ang!=b[i-1].ang) tot++;
            b[tot]=b[i];
        }
        n=tot,q[0]=b[1],q[1]=b[2];
        for(int i=3;i<=n;i++){
            while(l<r&&onright(q[r],q[r-1],b[i])) r--;
            while(l<r&&onright(q[l],q[l+1],b[i])) l++;
            q[++r]=b[i];
        }
        while(l<r&&onright(q[r],q[r-1],q[l])) r--;
        while(l<r&&onright(q[l],q[l+1],q[r])) l++;
        n=0,q[r+1]=q[l];
        for(int i=l;i<=r;i++)
            b[++n]=q[i],p[n]=glt(q[i],q[i+1]);
    }
    double S(Point *p,int n){
        double ans=0;
        p[n+1]=p[1];
        for(int i=1;i<=n;i++)
            ans+=p[i]*p[i+1];
        return fabs(ans)/2;
    }
    int t,m,n;
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d",&m);
            for(int i=1;i<=m;i++)
                scanf("%lf%lf",&a[i].x,&a[i].y);
            a[m+1]=a[1];
            for(int i=1;i<=m;i++)
                b[++n]=Line(a[i],a[i+1]-a[i]);
        }
        bpm(b,n,p);
        printf("%.3lf
    ",S(p,n));
        return 0;
    }
    
  • 相关阅读:
    IDEA连接 Oracle数据库
    什么是混合云备份
    什么是阿里云ACA认证
    什么是阿里云ACE认证
    什么是轻量应用服务器
    什么是时序时空数据库TSDB
    什么是数据管理DMS
    什么是分析型数据库PostgreSQL版
    阿里云多端小程序
    阿里云云计算ACP专业认证考试
  • 原文地址:https://www.cnblogs.com/nianheng/p/10013884.html
Copyright © 2011-2022 走看看