zoukankan      html  css  js  c++  java
  • [bzoj1043][HAOI2008]下落的圆盘【计算几何】

    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=1043
    【题解】
      考虑每个圆对答案的贡献,对于每个圆,枚举之后下落的圆盘,求出被覆盖的区间相对于X轴正方向的夹角的弧度值,然后排序,求出没被覆盖的弧度区间即可。
      时间复杂度O(N2logN)
      tips:c++的反三角函数可能由于精度问题返回nan。

    /* --------------
        user Vanisher
        problem bzoj-1043 
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    N       1010
    # define    eps     1e-10
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct point{
        double x,y;
    }c[N];
    struct node{
        double l,r;
    }q[N*2];
    double pi=acos(-1.0),r[N],ans;
    double sqr(double x){return x*x;}
    int num,n;
    double dis(point x, point y){
        return sqrt(sqr(x.x-y.x)+sqr(x.y-y.y));
    }
    double cosf(double a, double b, double c){
        double now=(sqr(a)+sqr(b)-sqr(c))/(2*a*b);
        if (now<=-1) now+=eps;
        if (now>=1) now-=eps;
        return now;
    }
    bool cmp(node x, node y){
        return x.l<y.l;
    }
    void join(double l, double r){
        q[++num]=(node){l,r};
    }
    int main(){
        n=read(); 
        for (int i=1; i<=n; i++)
            scanf("%lf%lf%lf",&r[i],&c[i].x,&c[i].y);
        for (int i=1; i<=n; i++){
            num=0;
            bool flag=false;
            for (int j=i+1; j<=n; j++){
                double d=dis(c[i],c[j]),tmp,o;
                if (d+r[i]<=r[j]){
                    flag=true; break;
                }
                if (d+r[j]<=r[i]) continue;
                if (d>=r[i]+r[j]) continue;
                tmp=acos(cosf(r[i],d,r[j]));
                o=acos(cosf(r[i],d,dis((point){c[i].x,c[i].y+r[i]},c[j])));
                if (c[i].x>c[j].x) o=2*pi-o;
                double l=o-tmp, r=o+tmp;
                if (l<0){
                    join(l+2*pi,2*pi);
                    join(0,r);
                }
                else if (r>2*pi){
                    join(l,2*pi);
                    join(0,r-2*pi);
                }
                else join(l,r);
            }
            if (flag) continue;
            sort(q+1,q+num+1,cmp);
            double nowr=0,now=0;
            for (int j=1; j<=num; j++){
                now=now+max(q[j].l-nowr,0.0);
                nowr=max(q[j].r,nowr);
            }
            now=now+2*pi-nowr;
            ans=ans+now*r[i];
        } 
        printf("%.3lf
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    python基础之====函数对象、函数嵌套、名称空间与作用域、装饰器
    python基础之函数基础
    pytho基础之文件处理
    python基础之字符编码
    python基础之数据类型与变量
    python基础之核心风格
    函数
    数据类型、字符编码、文件处理
    MongoDB
    Shell学习(三)——Shell条件控制和循环语句
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135967.html
Copyright © 2011-2022 走看看