zoukankan      html  css  js  c++  java
  • 【半平面交】bzoj2618 [Cqoi2006]凸多边形

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define EPS 0.0000001
    #define N 511
    typedef double db;
    const db PI=acos(-1.0);
    struct Point{db x,y;};
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b){return (Vector){a.x-b.x,a.y-b.y};}
    Vector operator * (const Vector &a,const db &k){return (Vector){a.x*k,a.y*k};}
    Vector operator + (const Vector &a,const Vector &b){return (Vector){a.x+b.x,a.y+b.y};}
    db Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
    struct Line
    {
        Point p; Vector v; db ang;
        Line(){}
        Line(const Point &a,const Point &b)
          {
            v=b-a;
            p=a;
            ang=atan2(v.y,v.x);
            if(ang<0) ang+=2.0*PI; 
          }
    };
    bool operator < (const Line &a,const Line &b){return a.ang<b.ang;}
    bool OnLeft(Line l,Point a){return Cross(l.v,a-l.p)>0;}
    Point GetJiaodian(Line a,Line b){return a.p+a.v*(Cross(b.v,a.p-b.p)/Cross(a.v,b.v));}
    int n;
    Point ps[N];
    Line q[N];
    int head=1,tail=1;
    Line ls[N];
    void BPMJ()
    {
        sort(ls+1,ls+n+1);
        q[1]=ls[1];
        for(int i=2;i<=n;++i)
          {
            while(head<tail&&(!OnLeft(ls[i],ps[tail-1]))) --tail;
            while(head<tail&&(!OnLeft(ls[i],ps[head]))) ++head;
            q[++tail]=ls[i];
            if(fabs(Cross(q[tail].v,q[tail-1].v))<EPS)
              {
                --tail;
                if(OnLeft(q[tail],ls[i].p))
                  q[tail]=ls[i];
              }
            if(head<tail)
              ps[tail-1]=GetJiaodian(q[tail-1],q[tail]);
          }
        while(head<tail&&(!OnLeft(q[head],ps[tail-1]))) --tail;
        ps[tail]=GetJiaodian(q[tail],q[head]);
    }
    int nn,mm;
    Point tmp[51];
    db area;
    int main()
    {
        scanf("%d",&nn);
        for(int i=1;i<=nn;++i)
          {
            scanf("%d",&mm);
            for(int j=1;j<=mm;++j) scanf("%lf%lf",&tmp[j].x,&tmp[j].y);
            for(int j=1;j<mm;++j) ls[++n]=Line(tmp[j],tmp[j+1]);
            ls[++n]=Line(tmp[mm],tmp[1]);
          }
        BPMJ();
        for(int i=head+1;i<tail;++i)
          area+=Cross(ps[i]-ps[head],ps[i+1]-ps[head]);
        printf("%.3lf
    ",area/2.0);
        return 0;
    }
  • 相关阅读:
    jsp 页面获取当前路径
    html5 页面音频
    微信关于网页授权access_token和普通access_token的区别
    Texlive source
    vscode 快捷键
    vscode setting
    vscode extension 插件管理
    what
    linux manual
    java tool type
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4587148.html
Copyright © 2011-2022 走看看