zoukankan      html  css  js  c++  java
  • bzoj 2178 圆的面积并【simpson积分】

    直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段。
    然而一定要去掉被其他圆完全覆盖的圆,否则会TLE

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double eps=1e-13;
    const int N=1005;
    int n,m;
    double mn=1e13,mx=-1e13;
    bool fl[N];
    struct cir
    {
    	double x,y,r;
    	double operator < (const cir &a) const
    	{
    		return r<a.r;
    	}
    }c[N];
    struct qwe
    {
    	double l,r;
    	qwe(double L=0,double R=0)
    	{
    		l=L,r=R;
    	}
    	bool operator < (const qwe &a) const
    	{
    		return l<a.l;
    	}
    }a[N];
    int cmp(double x)
    {
    	if(x<=eps&&x>=-eps)
    		return 0;
    	return x>0?1:-1;
    }
    double f(double x)
    {
    	int cnt=0;
    	for(int i=1;i<=n;i++)
    	{
    		double dis=fabs(c[i].x-x);
    		if(cmp(dis-c[i].r)<0)
    		{
    			double len=sqrt(c[i].r*c[i].r-dis*dis);
    			a[++cnt]=qwe(c[i].y-len,c[i].y+len);
    		}
    	}
    	if(!cnt)
    		return 0;
    	sort(a+1,a+1+cnt);
    	double l=a[1].l,r=a[1].r,ans=0;
    	for(int i=2;i<=cnt;i++)
    	{
    		if(cmp(a[i].l-r)<=0)
    			r=max(r,a[i].r);
    		else
    			ans+=r-l,l=a[i].l,r=a[i].r;
    	}
    	ans+=r-l;
    	return ans;
    }
    double sps(double l,double r,double now,double fl,double fr,double fm)
    {
    	double mid=(l+r)/2,ffl=f((l+mid)/2),ffr=f((mid+r)/2),p=(fl+fm+ffl*4)*(mid-l)/6,q=(fm+fr+ffr*4)*(r-mid)/6;
    	if(cmp(now-p-q)==0)
    		return now;
    	else
    		return sps(l,mid,p,fl,fm,ffl)+sps(mid,r,q,fm,fr,ffr);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
    		mn=min(mn,c[i].x-c[i].r),mx=max(mx,c[i].x+c[i].r);
    	}//cout<<"OK"<<endl;
    	sort(c+1,c+1+n);
    	for(int i=1;i<=n;i++)
    		for(int j=i+1;j<=n;j++)
    			if(cmp(sqrt((c[i].x-c[j].x)*(c[i].x-c[j].x)+(c[i].y-c[j].y)*(c[i].y-c[j].y))+c[i].r-c[j].r)<=0)
    			{		
    				fl[i]=1;
    				break;
    			}
    	for(int i=1;i<=n;i++)
    		if(!fl[i])
    			c[++m]=c[i];
    	n=m;
    	double fl=f(mn),fr=f(mx),fm=f((mn+mx)/2);
    	printf("%.3lf
    ",sps(mn,mx,(fl+4*fm+fr)*(mx-mn)/6,fl,fr,fm));
    	return 0;
    }
    
  • 相关阅读:
    poj3252Round Numbers
    poj2282The Counting Problem(组合)
    POJ1150he Last Non-zero Digit(组合)
    poj1715Hexadecimal Numbers(数位dp)
    Codeforces Beta Round #98 (Div. 2)(A-E)
    mysql被收购 用mariadb (转)
    vsftpd配置 (转)
    Linux文件目录结构详解 (转)
    Linux创建ftp并设置权限以及忘记ftp帐号(密码)修改 (转)
    Linux环境Nginx安装、调试以及PHP安装(转)
  • 原文地址:https://www.cnblogs.com/lokiii/p/8452281.html
Copyright © 2011-2022 走看看