zoukankan      html  css  js  c++  java
  • [BZOJ2178] 圆的面积并

    Description

    给出N个圆,求其面积并

    Input

    先给一个数字N ,N< = 1000 接下来是N行是圆的圆心,半径,其绝对值均为小于1000的整数

    Output

    面积并,保留三位小数

    Solution

    直接套(simpson)积分板子就好了,判掉圆包含的情况,然后每次求(f(x))的时候直接枚举所有的圆然后扫描线暴力搞,因为积分的意义下(f(a))的几何意义就是(x=a)被图形覆盖的长度。

    #include<bits/stdc++.h>
    using namespace std;
     
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
     
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    #define ll long long 
    
    const int maxn = 1e3+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    
    struct C{
    	int x,y,r,vis;
    	int operator < (const C &rhs) const {return r<rhs.r;}
    }a[maxn];
    int n;
    
    #define sqr(x) ((x)*(x))
    
    struct asd {
    	lf u,d;
    	int operator < (const asd &rhs) const {return d<rhs.d||(d==rhs.d&&u<rhs.u);}
    }rr[maxn];
    
    lf f(lf x) {
    	int t=0;
    	for(int i=1;i<=n;i++)
    		if(a[i].x-a[i].r<x&&x<a[i].x+a[i].r) {
    			if(a[i].vis) continue;
    			lf s=sqrt(sqr(a[i].r)-sqr(a[i].x-x));
    			rr[++t]=(asd){(lf)a[i].y+s,(lf)a[i].y-s};
    		}
    	sort(rr+1,rr+t+1);
    	lf ans=0,d=rr[1].d;
    	for(int i=1;i<=t;i++) 
    		if(d<rr[i].d) ans+=rr[i].u-rr[i].d,d=rr[i].u;
    		else if(d<rr[i].u) ans+=rr[i].u-d,d=rr[i].u;
    	return ans;
    }
    
    lf _int(lf l,lf r) {return (r-l)*(f(r)+f(l)+4.0*f((l+r)*0.5))/6.0;}
    
    lf simpson(lf l,lf r,lf res) {
    	lf mid=(l+r)*0.5,L=_int(l,mid),R=_int(mid,r);
    	if(fabs(L+R-res)<eps) return L+R;
    	else return simpson(l,mid,L)+simpson(mid,r,R);
    }
    
    int main() {
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i].x),read(a[i].y),read(a[i].r);
    	sort(a+1,a+n+1);
    	for(int i=1;i<=n;i++)
    		for(int j=i+1;j<=n;j++)
    			if(sqr(a[i].x-a[j].x)+sqr(a[i].y-a[j].y)<=sqr(a[j].r-a[i].r)) {
    				a[i].vis=1;break;
    			}
    	printf("%.3lf
    ",simpson(-2000.00,2000.00,_int(-2000.00,2000.00)));
    	return 0;
    }
    
  • 相关阅读:
    January 25th, 2018 Week 04th Thursday
    January 24th, 2018 Week 04th Wednesday
    January 23rd, 2018 Week 04th Tuesday
    January 22nd, 2018 Week 04th Monday
    January 21st, 2018 Week 3rd Sunday
    January 20th, 2018 Week 3rd Saturday
    January 19th, 2018 Week 3rd Friday
    January 18th, 2018 Week 03rd Thursday
    January 17th, 2018 Week 03rd Wednesday
    January 16th, 2018 Week 03rd Tuesday
  • 原文地址:https://www.cnblogs.com/hbyer/p/10541967.html
Copyright © 2011-2022 走看看