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;
    }
    
  • 相关阅读:
    手起刀落-一起来写经典的贪吃蛇游戏
    同步、异步、回调执行顺序之经典闭包setTimeout分析
    起步
    设计模式之单例模式与场景实践
    青春是如此美好,又怎忍平凡度过
    nvm管理不同版本的node和npm
    起步
    基础
    调用wx.request接口时需要注意的几个问题
    微信小程序实现各种特效实例
  • 原文地址:https://www.cnblogs.com/hbyer/p/10541967.html
Copyright © 2011-2022 走看看