zoukankan      html  css  js  c++  java
  • bzoj2618: [Cqoi2006]凸多边形

    Description

    逆时针给出n个凸多边形的顶点坐标,求它们交的面积。例如n=2时,两个凸多边形如下图:

    则相交部分的面积为5.233。

    Input

    第一行有一个整数n,表示凸多边形的个数,以下依次描述各个多边形。第i个多边形的第一行包含一个整数mi,表示多边形的边数,以下mi行每行两个整数,逆时针给出各个顶点的坐标。

    Output

        输出文件仅包含一个实数,表示相交部分的面积,保留三位小数。

    凸多边形交转为半平面交

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    const double pi=acos(-1),_0=1e-5;
    struct vec{double x,y;};
    struct line{vec p,v;double a;
    void cal(){
        if(v.y==0&&v.x<0)a=pi;
        else a=atan2(v.y,v.x);
    }
    };
    vec operator+(vec a,vec b){return (vec){a.x+b.x,a.y+b.y};}
    vec operator-(vec a,vec b){return (vec){a.x-b.x,a.y-b.y};}
    vec operator*(vec a,double b){return (vec){a.x*b,a.y*b};}
    double operator*(vec a,vec b){return a.x*b.y-b.x*a.y;}
    bool operator<(line a,line b){return a.a<b.a;}
    vec operator&(line a,line b){return a.p+a.v*((b.v*(a.p-b.p))/(a.v*b.v));}
    bool chk(line a,vec b){return a.v*(b-a.p)>0;}
    double ans=0;
    int n,m;
    line ls[1024],q[1024];
    vec ps[1024];
    int l=0,r=0,p=0;
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&m);
            for(int i=0;i<m;i++){
                scanf("%lf%lf",&ps[i].x,&ps[i].y);
            }
            ps[m]=ps[0];
            for(int i=0;i<m;i++){
                ls[p].p=ps[i];
                ls[p].v=ps[i+1]-ps[i];
                ls[p].cal();
                p++;
            }
        }
        std::sort(ls,ls+p);
        q[0]=ls[0];
        for(int i=1;i<p;i++){
            while(l<r&&!chk(ls[i],q[r-1]&q[r]))--r;
            while(l<r&&!chk(ls[i],q[l]&q[l+1]))++l;
            q[++r]=ls[i];
            if(fabs(q[r].v*q[r-1].v)<_0){
                --r;
                if(chk(q[r],ls[i].p))q[r]=ls[i];
            }
        }
        while(l<r&&!chk(q[l],q[r-1]&q[r]))--r;
        if(r-l<=1){
            puts("0.000");
            return 0;
        }
        for(int i=l;i<r;i++)ps[i]=(q[i]&q[i+1]);
        ps[r]=(q[r]&q[l]);
        for(int i=l+1;i<r;i++)ans+=fabs((ps[i]-ps[l])*(ps[i+1]-ps[l]))*.5;
        printf("%.3lf
    ",ans);
        return 0;
    }
  • 相关阅读:
    scrapy模拟用户登录
    我为什么选择Vim
    关于72键配列键盘的想法
    vim配图
    解决一些python的问题记录
    ros资料记录,详细阅读
    C语言的历史
    将制定目录家到系统PATH环境变量中
    让vim更加智能化
    如何自定义路径
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5622295.html
Copyright © 2011-2022 走看看