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\n",sps(mn,mx,(fl+4*fm+fr)*(mx-mn)/6,fl,fr,fm));
    return 0;
}

原文地址:https://www.cnblogs.com/lokiii/p/8452281.html

时间: 2024-10-29 05:00:19

bzoj 2178 圆的面积并【simpson积分】的相关文章

BZOJ 2178 圆的面积并 Simpson积分

题意:链接 方法: Simpson积分 解析: 这题是有正解的=-= 不过Simpson积分可过. 首先 ∫rlf(x)=(r?l)(f(l)+f(r)+4f(mid))6 然后就强行递归搞就行了. 至于f(i)的值,在本题就是x=i这条直线与所有可以相交的圆的截线长的和. 这个的话用勾股定理求即可. 然后有一个方法 Simpson积分自适应法=-= 我们只需要强行套用公式,然后检验左半边的如上函数值加上右半边的如上函数值与我们强行套用公式得出来的值是否在精度范围允许内,如果在的话直接retur

BZOJ 2178 圆的面积并 ——Simpson积分

[题目分析] 史上最良心样例,史上最难调样例. Simpson积分硬上. 听说用long double 精度1e-10才能过. 但是double+1e-6居然过了. [代码] #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <map> #include <set> #include <queue> #incl

BZOJ 2178: 圆的面积并 [辛普森积分 区间并]

2178: 圆的面积并 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1740  Solved: 450[Submit][Status][Discuss] Description 给出N个圆,求其面积并 Input 先给一个数字N ,N< = 1000 接下来是N行是圆的圆心,半径,其绝对值均为小于1000的整数 Output 面积并,保留三位小数 太可怕了!!!!!! 直接上辛普森积分 函数值就是x=..线上的区间并 区间并直接排序扫描就可以了

BZOJ 2178 圆的面积并 Simpson自适应公式

题目大意:给定n个圆,求面积并 直接暴力套用Simpson自适应公式就行了 对于每一个x值,求出F(x)的方法是求出所有圆在直线x=x(重了233)上的截取区间 然后求区间并 返回区间长度即是F值 这样正常写就过样例了 然后 WA了... 尼玛我样例都过了你跟我说WA? 下面是注意事项: 1.此题卡精度 EPS要设为1e-13 设为1e-12会WA 2.标程精度不够 不能用long double 否则会WA 3.这样会TLE 解决方法是预先将内含与其他圆的圆删掉 然后就能过了 这明显是卡数据啊-

【BZOJ】2178: 圆的面积并

http://www.lydsy.com/JudgeOnline/problem.php?id=2178 题意:给出n<=1000个圆,求这些圆的面积并 #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> #include <queue> #in

bzoj 1502 月下柠檬树【Simpson积分】

投影到地面之后,会发现圆形在平行光下面积和形状是不会变的,也就是所要求的图形是若干个圆和把相邻两个圆连起来的公切线所组成的. 公切线和圆间距瞎求一下就行,注意要去掉被完全覆盖的圆 然后simpson即可 eps大概1e-6 #include<iostream> #include<cstdio> #include<cmath> using namespace std; const int N=1005; const double eps=1e-6,inf=1e15; do

【BZOJ】【2178】圆的面积并

自适应辛普森积分 Orz Hzwer 辛普森真是个强大的东西……很多东西都能积= = 这题的正解看上去很鬼畜,至少我这种不会计算几何的渣渣是写不出来……(对圆的交点求图包,ans=凸包的面积+一堆弓形的面积,另外还有中空的情况……那种凸包怎么求啊喂!) 1 /************************************************************** 2 Problem: 2178 3 User: Tunix 4 Language: C++ 5 Result: A

BZOJ 2178 Simpson积分

思路: 我发现能用Simpson积分水的题  好像都是裸题诶233333 //By SiriusRen #include <bits/stdc++.h> using namespace std; #define pr pair<double,double> const int N=1050; int n,ban[N];double inf=1e100,l=inf,r=-inf;pr p[N]; struct Point{int x,y;}; double dis(Point a,P

BZOJ 1502 [NOI2005]月下柠檬树 自适应Simpson积分

题意:链接 方法:自适应Simpson积分 解析: 大半夜刷这道题真是爽歪歪. 求一棵树(圆锥加圆台组成)在平面上的投影的面积. 给定投影角度(0.3 < alpha <= pi/2). 先来想想圆的投影是什么样子 还是他自己. 再想圆锥投影是什么样子 一个点加一个圆,并且有这个点与该圆的两条切线(该点在圆内部时没有切线) 再想圆台 两个圆,加上两个圆的外公切线组成的一坨图形. 不妨随意画一个. 好难画- -! 大概就转化成这个样子了. 观察这个图形- 轴对称啊- -! 这意味着我们好多东西都