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;
    }
    
  • 相关阅读:
    2013暑假集训B组训练赛第二场
    2013暑假集训B组训练赛第二场
    2013暑假集训B组训练赛第二场
    2013暑假集训B组训练赛第二场
    SPOJ ANARC05H 计数DP
    HDU 2586 LCA-Tarjan
    POJ 1330 LCA最近公共祖先 离线tarjan算法
    Codeforces 176B 经典DP
    UVA 10564 计数DP
    HDU 4901 多校4 经典计数DP
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9077963.html
Copyright © 2011-2022 走看看