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

    题目传送门

    题目大意

    给出 (n) 个圆,求它们并的面积大小。

    (nle 10^3)

    思路

    如果您不会自适应辛普森法,请戳这里学习

    其实我们发现,如果我们设 (f(x)) 表示 (x=x) 这条直线与所有圆的交的线段的长度,那么答案就是:

    [int^{+infty}_{-infty}f(x),dx ]

    然后你发现 (f(x)) 可以在 (Theta(n)) 的时间复杂度内解决,而实际上范围也达不到 (infty),实际操作中直接取 (2000) 就可以了(实际上你按圆的左右边界来做自适应辛普森法会有一个小小的误差)

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define double long double
    #define Int register int
    #define MAXN 1005
    #define eps 1e-12
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,top;
    struct Cir{double x,y,r;}a[MAXN];
    struct Line{
    	double l,r;
    	bool operator < (const Line &p)const{return l < p.l;}
    }p[MAXN];
    
    double Sqr (double x){return x * x;}
    double f (double x){//这些园跟x=x交的长度 
    	top = 0;
    	for (Int i = 1;i <= n;++ i)
    		if (a[i].x - a[i].r <= x && x <= a[i].x+ a[i].r){
    			double len = sqrt (Sqr (a[i].r) - Sqr (a[i].x - x));
    			p[++ top] = Line {a[i].y - len,a[i].y + len};
    		}
    	sort (p + 1,p + top + 1);
    	double ret = 0,l = -1e9,r = -1e9;
    	for (Int i = 1;i <= top;++ i) 
    		if (p[i].l - r > eps) ret += r - l,l = p[i].l,r = p[i].r;
    		else if (p[i].r - r > eps) r = p[i].r;
    	return ret + r - l;
    }
    
    double Simpson (double l,double r){return (r - l) * (f (l) + f(r) + 4.0 * f ((l + r) / 2)) / 6;}
    double asr (double l,double r,double ans){//储存ans纯粹是为了卡常 
    	double mid = (l + r) / 2,lans = Simpson (l,mid),rans = Simpson (mid,r);
    	if (fabs (lans + rans - ans) < eps) return ans;
    	else return asr (l,mid,lans) + asr (mid,r,rans);
    }
    double asr (double l,double r){return asr (l,r,Simpson (l,r));}
    
    signed main(){
    	read (n);
    	for (Int i = 1;i <= n;++ i) scanf ("%Lf%Lf%Lf",&a[i].x,&a[i].y,&a[i].r);
    	double l = 1e9,r = -1e9;
    	for (Int i = 1;i <= n;++ i) l = min (l,a[i].x - a[i].r),r = max (r,a[i].x + a[i].r);
    	printf ("%.3Lf
    ",asr (l+eps,r-eps));
    	return 0;
    }
    
  • 相关阅读:
    Python基础Day2
    HDU
    HDU
    BZOJ
    Gym
    UVA
    UVA
    UVA
    UVA
    BZOJ
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13646802.html
Copyright © 2011-2022 走看看