Loading

HDU 1724:Ellipse(自适应辛普森积分)

题目链接

题意

给出一个椭圆,问一个[l, r] 区间(蓝色区域)的面积是多少。

思路

自适应辛普森积分

具体一些分析如上。

很方便,套上公式就可以用了。

注意 eps 的取值影响了跑的时间,因为决定了递归的深度。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 11;
const double eps = 1e-5; // 精度对时间有影响
double a, b, l, r;

// 被积函数,这里是椭圆
double F(double x) {
    return sqrt(b * b - b * b * x * x / a / a);
}

// 三点simpson法
double simpson(double a, double b) {
    double c = a + (b - a) / 2; // (a + b) / 2
    return (F(a) + 4 * F(c) + F(b)) * (b - a) / 6.0;
}

//自适应Simpson公式(递归过程).已知整个区间[a,b]上的三点Simpson值A
double asr(double a, double b, double eps, double A) {
    double c = a + (b - a) / 2;
    double L = simpson(a, c), R = simpson(c, b);
    if(fabs(L + R - A) <= eps * 15) return L + R + (L + R - A) / 15.0;
    return asr(a, c, eps / 2, L) + asr(c, b, eps / 2, R);
}

double ASR(double a, double b, double eps) {
    return asr(a, b, eps, simpson(a, b));
}

int main() {
    int t; scanf("%d", &t);
    while(t--) {
        scanf("%lf%lf%lf%lf", &a, &b, &l, &r);
        printf("%.3f\n", ASR(l, r, eps) * 2);
    } return 0;
}
posted @ 2017-10-12 00:36  Shadowdsp  阅读(289)  评论(0编辑  收藏  举报