zoukankan      html  css  js  c++  java
  • BZOJ 1043: [HAOI2008]下落的圆盘

    Description

    求几个圆交起来的周长..(nleqslant 10^3)

    Solution

    计算几何.

    圆圆求交..

    Code

    /**************************************************************
        Problem: 1043
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:520 ms
        Memory:1308 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
      
    namespace CG {
        typedef double LD;
          
        const LD Pi = M_PI;
        const LD PI = 2 * acos(0.0);
        const LD eps = 1e-12;
        #define sqr(x) ((x)*(x))
          
        int dcmp(LD x) { return fabs(x)<eps?0:(x<0?-1:1); }
          
        struct Point {
            LD x,y;
            Point(LD _x=0,LD _y=0) :x(_x),y(_y) {}
            void out() { cout<<"("<<x<<","<<y<<")"; }
        };
        typedef Point Vector;
          
        int cmpx(const Point &a,const Point &b) { return dcmp(a.x-b.x)==0?a.y<b.y:a.x<b.x; }
          
        Vector operator + (const Vector &a,const Vector &b) { return Vector(a.x+b.x,a.y+b.y); }
        Vector operator - (const Vector &a,const Vector &b) { return Vector(a.x-b.x,a.y-b.y); }
        Vector operator * (const Vector &a,LD b) { return Vector(a.x*b,a.y*b); }
        Vector operator / (const Vector &a,LD b) { return Vector(a.x/b,a.y/b); }
        bool operator == (const Point &a,const Point &b) { return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; }
          
        LD Dot(Vector a,Vector b) { return a.x*b.x+a.y*b.y; }
        LD Cross(Vector a,Vector b) { return a.x*b.y-b.x*a.y; }
        Vector Rot(Vector a,LD rd) { return Vector(a.x*cos(rd)-a.y*sin(rd),a.x*sin(rd)+a.y*cos(rd)); }
        LD get_l(Vector a) { return sqrt(Dot(a,a)); }
        LD get_d(Point a,Point b) { return sqrt(Dot(a-b,a-b)); }
        LD get_a(Vector a) { return atan2(a.y,a.x); }
        LD get_a(Vector a,Vector b) { return acos(Dot(a,b)/get_l(a)/get_l(b)); } 
        LD get_s(Point a,Point b,Point c) { return Cross(b-a,c-a)/2.0; }
          
        struct Line {
            Point p;
            Vector v;
            Line(Point a=Point(),Point b=Point()):p(a),v(b-a) {  } 
            LD get_l() { return sqrt(Dot(v,v)); } 
            Point get_p(LD t) { return p+v*t; }
            Point get_s() { return p; }
            Point get_t() { return p+v; }
        };
          
        struct Circle {
            Point c;
            LD r;
            Point get_p(LD t) { return c+Point(cos(t)*r,sin(t)*r); }
            LD get_rd(Point a,Point b) { return get_a(a-c,b-c); }
            LD get_l(LD rd) { return r*rd; } 
        };
          
        int get_c_l(Line L,Circle C,vector<Point> &res) {
            LD a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;
            LD e=sqr(a)+sqr(c),f=2.0*(a*b+c*d),g=sqr(b)+sqr(d)-sqr(C.r);
            LD dt=f*f-4*e*g;
            if(dcmp(dt)<0) return 0;
            if(dcmp(dt)==0) return res.push_back(L.get_p(-f/(2.0*e))),1;
            LD x1=(-f-sqrt(dt))/(2.0*e),x2=(-f+sqrt(dt))/(2.0*e);
            if(x1>x2) swap(x1,x2);
            res.push_back(L.get_p(x1)),res.push_back(L.get_p(x2));return 2;
        }
        int get_c_c(Circle A,Circle B,vector<Point> &res) {
            LD d=get_l(A.c-B.c);
            if(dcmp(d)==0) return dcmp(A.r-B.r)==0?-1:0;
            if(dcmp(A.r+B.r-d)<0) return 0;
            if(dcmp(fabs(A.r-B.r)-d)>0) return 0;
              
            LD a=get_a(B.c-A.c);
            LD rd=acos((sqr(A.r)+sqr(d)-sqr(B.r))/(2.0*A.r*d));
              
            Point p1,p2;
            p1=A.get_p(a+rd),p2=A.get_p(a-rd);
              
            res.push_back(p1);
            if(p1==p2) return 1;
            res.push_back(p2);
            return 2;
        }
          
        /*---io---*/  
        ostream & operator << (ostream &os,const Point &p) { os<<p.x<<" "<<p.y;return os; }
        istream & operator >> (istream &is,Point &p) { is>>p.x>>p.y;return is; }
        ostream & operator << (ostream &os,const Circle &C) { os<<C.c<<" "<<C.r;return os; }
        istream & operator >> (istream &is,Circle &C) { is>>C.c>>C.r;return is; }
    };
      
    using namespace CG;
     
    #define mpr make_pair
      
    int n;
    LD ans;
    vector<Circle> cr;
    vector<Line> cl;
    vector<Point> ls;
    vector<Point> cp;
      
    void add_l(vector<Point> &s,LD x,LD y) {
        if(x>y) s.push_back(Point(x,Pi)),s.push_back(Point(-Pi,y));
        else ls.push_back(Point(x,y));
    }
    int chk(Circle A,Circle B) {
        LD d=get_l(A.c-B.c);
        if(dcmp(B.r-A.r-d)>0) return 1;
        return 0;
    }
    LD get_ans(Circle c,int id) {
        ls.clear();
        //O-O jiaodian
        for(int i=id+1;i<n;i++) {
            cp.clear();
            if(chk(c,cr[i])) return 0;
            if(get_c_c(c,cr[i],cp)<2) continue;
            LD xx=get_a(cp[0]-c.c),yy=get_a(cp[1]-c.c);
            add_l(ls,yy,xx);
        }
        if(!ls.size()) return c.get_l(2*Pi);
        sort(ls.begin(),ls.end(),cmpx);
    //  for(int i=0;i<(int)ls.size();i++) cout<<ls[i].x<<" "<<ls[i].y<<endl;
        LD lx=ls[0].x,ly=lx,res=0;
        for(int i=0;i<(int)ls.size();i++) {
            if(dcmp(ls[i].x-ly)>0) res+=ly-lx,lx=ls[i].x;
            ly=max(ly,ls[i].y);
        }res+=ly-lx;
        return c.get_l(2*Pi-res);
    }
    void Solve() {
        scanf("%d",&n);
        Circle cc;
        cr.clear(),ls.clear(),cp.clear(),ans=0;
          
        for(int i=1;i<=n;i++) {
            scanf("%lf%lf%lf",&cc.r,&cc.c.x,&cc.c.y);
            cr.push_back(cc);
        }
        for(int i=0;i<n;i++) {
            LD tmp=get_ans(cr[i],i);
            ans+=tmp;
        //  cout<<tmp<<endl;
        }printf("%.3lf
    ",ans);
    }
      
    int main() {
        Solve();
        return 0;
    }
    

      

  • 相关阅读:
    dedecms代码研究五
    dedecms代码研究四
    判断有没有真正点击打印
    SAP中删除假脱机请求
    商品扩地点不成功
    记录一些使用的abap小程序帮助开发
    sap abap 程序 中使用 FTP . <转载>
    SM37 后台调试
    ftp上传下载| 图片上传下载
    ALV调用的几个标准函数 <转自 思微随想>
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6721254.html
Copyright © 2011-2022 走看看