• bzoj2178:圆的面积并


    题意:http://www.lydsy.com/JudgeOnline/problem.php?id=2178

    sol  :是谁.......是谁往题里下毒......

       辛普森积分,每次判断左边+右边是否-lastans是否<eps,递归处理

       公式:f'(l~r)=(r-l)*(f(l)+f(r)+4*f(mid))/6

       f(i)表示x=i时与圆相交部分的和,然后直接上辛普森积分就可以水过了

       P.S.此题有坑QAQ

         eps设成1e-13才能过,1e-12会WA

         需要剪枝:将包含在其他圆内的圆删去

       P.S.此题有毒.....不知道为什么排序时写cmp就TLE了,然而重载运算符就AC了也是很迷啊QAQ

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define eps 1e-13
    using namespace std;
    const int Mx=1010;
    int n,tot,st,to;
    bool vis[Mx];
    double L[Mx],R[Mx];
    struct Node { double x,y,r; } str[Mx];
    struct Line { double l,r; } line[Mx];
    double dis(Node a,Node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }
    bool cmp1(Node a,Node b) { return a.r<b.r; }
    bool cmp2(Node a,Node b) { return a.x-a.r<b.x-b.r; }
    bool operator < (Line a,Line b) { return a.l<b.l; }
    double cal(double fl,double fmid,double fr,double r_l) { return r_l*(fl+fr+4*fmid)/6; }
    double get_f(double x)
    {
        double ans=0; tot=0;
        for(int i=1;i<=n;i++)
            if(x>=L[i]&&x<=R[i])
            {
                double len=sqrt(str[i].r*str[i].r-(str[i].x-x)*(str[i].x-x));
                line[++tot].l=str[i].y-len; line[tot].r=str[i].y+len;
            }
        sort(line+1,line+tot+1);
        for(int i=1,j;i<=tot;i++)
        {
            double minl=line[i].l,minr=line[i].r;
            for(j=i+1;j<=tot;j++)
            {
                if(line[j].l>minr) break;
                if(line[j].r>minr) minr=line[j].r;
            }
            ans+=minr-minl; i=j-1;
        }
        return ans;
    }
    double simpson(double l,double r,double mid,double fl,double fr,double fmid,double lastans)
    {
        double mid1=(l+mid)/2,mid2=(mid+r)/2,fmid1=get_f(mid1),fmid2=get_f(mid2);
        double ans1=cal(fl,fmid1,fmid,mid-l),ans2=cal(fmid,fmid2,fr,r-mid);
        if(fabs(ans1+ans2-lastans)<eps) return ans1+ans2;
        return simpson(l,mid,mid1,fl,fmid,fmid1,ans1)+simpson(mid,r,mid2,fmid,fr,fmid2,ans2);
    }
    void solve()
    {
        double ans=0.00;
        for(int i=1,j;i<=n;i++)
        {
            st=i; double minl=L[i],minr=R[i],minmid;
            for(j=i+1;j<=n;j++)
            {
                if(L[j]>minr) break;
                if(R[j]>minr) minr=R[j];
            }
            to=j-1,i=to,minmid=(minl+minr)/2;
            double fl=get_f(minl),fr=get_f(minr),fmid=get_f(minmid),lstans=cal(fl,fmid,fr,minr-minl);
            ans+=simpson(minl,minr,minmid,fl,fr,fmid,lstans);
        }
        printf("%.3lf",ans);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&str[i].x,&str[i].y,&str[i].r);
        sort(str+1,str+1+n,cmp1);
        //剪枝 
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                if(fabs(str[j].r-str[i].r)>=dis(str[j],str[i]))
                {
                    vis[i]=1; break;
                }
        for(int i=1,tmp=0,mx=n;i<=mx;i++) if(!vis[i]) str[++tmp]=str[i],n=tmp;
        //
        sort(str+1,str+1+n,cmp2);
        for(int i=1;i<=n;i++) L[i]=str[i].x-str[i].r,R[i]=str[i].x+str[i].r;
        solve();
        return 0;
    }
  • 相关阅读:
    http协议详解
    001http协议
    django整合版
    数据库整合版
    并发编程整合版
    网络编程整合版
    面向对象编程
    LeetCode OJ:Binary Tree Postorder Traversal(后序遍历二叉树)
    LeetCode OJ:Populating Next Right Pointers in Each Node II(指出每一个节点的下一个右侧节点II)
    LeetCode OJ:Populating Next Right Pointers in Each Node(指出每一个节点的下一个右侧节点)
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6618272.html
Copyright © 2020-2023  润新知