zoukankan      html  css  js  c++  java
  • 【BZOJ】2178: 圆的面积并

    题解

    道理我都懂,可这精度卡得也太过分了吧

    1e-10 AC 1e-12 WA,maya

    就是把每个横坐标上圆覆盖的纵坐标长度求出来,对这个函数做一次simpson就行

    代码

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    //#define ivorysi
    #define pb push_back
    #define MAXN 1005
    #define eps 1e-10
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long int64;
    typedef double db;
    int N;
    bool dcmp(db a,db b) {
        return fabs(a - b) <= eps;
    }
    struct cir {
        db x,y,r;
        friend bool operator < (const cir &a,const cir &b) {
    	return (a.x - a.r) < (b.x - b.r);
        }
    }C[MAXN];
    pair<db,db> L[MAXN];
    inline db o (db x) {return x * x;}
    
    db Calc(db x) {
        int tot = 0;
        for(int i = 1 ; i <= N ; ++i) {
    	if(x < C[i].x - C[i].r - eps || x > C[i].x + C[i].r + eps) continue;
    	db t = sqrt(o(C[i].r) - o(x - C[i].x));
    	L[++tot] = mp(C[i].y - t,C[i].y + t);
        }
        sort(L + 1,L + tot + 1);
        if(!tot) return 0;
        db res = 0,s = L[1].fi,mx = L[1].se;
        for(int i = 2 ; i <= tot ; ++i) {
    	if(L[i].fi > mx) {
    	    res += mx - s;
    	    s = L[i].fi;
    	}
    	mx = max(mx,L[i].se);
        }
        res += mx - s;
        return res;
    }
    db Simpson(db L,db R,db fl,db fmid,db fr) {
        db mid = (L + R) / 2;
        db Slr = (R - L) * (fl + 4 * fmid + fr) / 6;
        db p = Calc((L + mid) / 2),q = Calc((mid + R) / 2);
        db Sl = (mid - L) * (fl + 4 * p + fmid) / 6;
        db Sr = (R - mid) * (fmid + 4 * q + fr) / 6;
        if(dcmp(Slr,Sl + Sr)) return Sl + Sr;
        else return Simpson(L,mid,fl,p,fmid) + Simpson(mid,R,fmid,q,fr); 
    }
    void Solve() {
        scanf("%d",&N);
        for(int i = 1 ; i <= N ; ++i) scanf("%lf%lf%lf",&C[i].x,&C[i].y,&C[i].r);
        db res = Simpson(-2001,2001,Calc(-2001),Calc(0),Calc(2001));
        printf("%.3lf
    ",res);
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    【转】C#进阶系列——WebApi 接口参数不再困惑:传参详解
    微信内测小程序,苹果你怎么看?
    给你一个团队,你应该怎么管?
    ios修改产品名
    【原创】windows下搭建vue开发环境+IIS部署
    【原】“系统”重新启动
    Ubuntu root密码修改
    【转】网络编程常见问题总结
    Python + Selenium -Python 3.6 3.7 安装 PyKeyboard PyMouse
    python3 获取当前路径及os.path.dirname sys.path.dirname的使用
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9077963.html
Copyright © 2011-2022 走看看