zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6618272.html
Copyright © 2011-2022 走看看