天天看點

HDU - 1724: Ellipse

題目連結:​​點選打開連結​​

題目大意:求出所給橢圓的藍色陰影部分面積。由于陰影部分是不規則圖形,是以,可以考慮用數值分析的辦法-辛普森公式或者牛頓-科特斯公式求積分法,為了增加精度,可以用二分法疊代細化。

解題思路:

這是一道 自适應辛普森積分 的入門題,也是我寫的第一道辛普森積分。

題目就是求兩條線所夾的橢圓的面積。這是個标準的橢圓,其中心在原點。我好像看到了題目連橢圓面積公式都給了,然而并沒有任何用,直接上辛普森!

根據橢圓的對稱性,我們求x軸上方的面積然後乘以2就是答案。根據橢圓方程

HDU - 1724: Ellipse

,構造函數 

HDU - 1724: Ellipse

,其中 y>0,然後對此函數進行自适應辛普森積分就可以了。

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f

using namespace std;

typedef long long ll;

double a,b;

double f(double x)
{
    return b*sqrt(1-(x*x)/(a*a));
}

double simpson(double l, double r)
{
    double mid=l+(r-l)/2;
    return (f(l)+4*f(mid)+f(r))*(r-l)/6;
}

double integral(double l, double r, double eps)
{
    // 這裡 mid 不能定義為全局變量,因為最後一條 return 有兩個 mid 若是全局,第二個遞歸的 mid 會有更換
    double mid=l+(r-l)/2;
    double st=simpson(l,r), sl=simpson(l,mid), sr=simpson(mid,r);
    if(fabs(sl+sr-st)<=15*eps) return sl+sr+(sl+sr-st)/15;
    // 這裡直接 return st; 會 WA
    return integral(l,mid,eps/2)+integral(mid,r,eps/2);
}

int main()
{
    int n; scanf("%d",&n);
    while(n--)
    {
        double l,r,eps=1e-4;
        scanf("%lf%lf%lf%lf",&a,&b,&l,&r);
        printf("%.3f\n",2*integral(l,r,eps));
    }

    return 0;
}