zoukankan      html  css  js  c++  java
  • BZOJ2178:圆的面积并——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2178

    给出N个圆,求其面积并。

    simpson,将圆劈成两半,假设上面的叫上壳,下面的叫下壳,对这两个壳分别做一遍simpson,相减就是答案。

    当然优化时间可以去掉完全包含的圆。

    以及相减的时候注意同一坐标的不同解,我们要求他的并。

    另外精度死活调不对,参考了:https://www.cnblogs.com/SfailSth/p/6360277.html的代码才过orz

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const int N=1010;
    const dl eps=1e-8;
    const dl INF=2000;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct cir{
        int x,y,r;
    }p[N];
    int n,tag[N];
    struct node{
        dl l,r;
    }q[N];
    inline bool cmp1(node a,node b){
        return a.l<b.l||(a.l==b.l&&a.r<b.r);
    }
    inline bool cmp2(cir a,cir b){
        return a.r<b.r;
    }
    inline dl f(dl x){
        int cnt=0;
        for(int i=1;i<=n;i++){
        if(fabs(p[i].x-x)-p[i].r<-eps){
            dl t=sqrt(p[i].r*p[i].r-(x-p[i].x)*(x-p[i].x));
            q[++cnt].l=p[i].y-t;
            q[cnt].r=p[i].y+t;
        }
        }
        sort(q+1,q+cnt+1,cmp1);
        dl h=-INF,ans=0;
        for(int i=1;i<=cnt;i++){
        if(h<q[i].l)ans+=q[i].r-q[i].l,h=q[i].r;
        else if(h<q[i].r)ans+=q[i].r-h,h=q[i].r;
        }
        return ans;
    }
    inline dl simpson(dl l,dl r){
        dl mid=(l+r)/2;
        return (f(l)+4*f(mid)+f(r))*(r-l)/6;
    }
    inline dl asr(dl l,dl r,dl ans){
        dl mid=(l+r)/2;
        dl l1=simpson(l,mid),r1=simpson(mid,r);
        if(fabs(l1+r1-ans)<eps)return l1+r1;
        return asr(l,mid,l1)+asr(mid,r,r1);
    }
    int main(){
        n=read();
        for(int i=1;i<=n;i++){
        p[i].x=read(),p[i].y=read(),p[i].r=read();
        }
        sort(p+1,p+n+1,cmp2);
        for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int x=p[i].x-p[j].x,y=p[i].y-p[j].y,r=p[j].r-p[i].r;
            if(x*x+y*y<=r*r){
            tag[i]=1;break;
            }
        }
        }
        int tot=0;
        for(int i=1;i<=n;i++)if(!tag[i])p[++tot]=p[i];
        n=tot;
        printf("%.3lf
    ",asr(-INF,INF,simpson(-INF,INF)));
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    Python上下文管理器
    面向对象(三)【类的特殊成员及高级特性】
    面向对象(二)【类的成员及修饰符】
    面向对象(一)【“类与对象”的概念及特性】
    leetcode【14题】Longest Common Prefix
    Spring Cloud之Zuul
    Spring Cloud之Hystrix
    SpringCloud之Eureka、Ribbon
    synchronized块中的wait()、nofity()、nofityAll()方法
    IP的分类以及子网划分、网络设置
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9072016.html
Copyright © 2011-2022 走看看