HDU1724自适应Simpson积分

【HDU1724自适应Simpson积分】博观而约取,厚积而薄发。这篇文章主要讲述HDU1724自适应Simpson积分相关的知识,希望能为你提供帮助。
1.??题目链接??。题目的意思很简单,就是求阴影部分的面积,图形是一个椭圆。
2.思路:这个做法当然有很多种了,最暴力的就是直接积分了,用一下三角换元也是很简单的就搞定了。其实化简到最后可能涉及到反三角函数的化简,这个就量力而行了呗,有能力继续的,就可以继续(其实没必要,也不是做数学题),搞不明白反三角怎么化简得,直接就写公式上去。第二种方法就是Simpson积分法了,自适应得Simpson积分很简单得就解决了这个问题。第三种,也是我百思不得为什么WA了得一种,就是使用仿射变换,我们知道,可以把椭圆通过坐标系得放缩变成一个圆,然后在圆里面把面积求出来,因为这个坐标变换是按照比例变换得,所以面积也是成比例的,比如:我们做这样的变换:x0=x,y0=(a/b)y,反解出x,y带入就可以的到一个关于x0,y0的方程,这是一个圆,半径就是a.那么我们知道两条直线在这个变换下还是不变的,所以区间还是[l,r],那么在这个圆里面的面积和之前面积的关系就是:s0=(a/b)s.我们只要把s0求出来就行了,s0很简单求了,分成三个部分,左右的三角形,加上中间的扇形,中间的圆心角用余弦定理求出来,面积搞定,再转代回去,就可以得到s了。emmmmm,可是莫名其妙的WA了,也不知怎么回事,在WA了五六发之后,我一怒之下撸了个Simpson A了它。代码如下:

//#include"stdafx.h"
//#include< iostream>
//#include< cmath>
//using namespace std;
//#pragma warning(disable:4996)
//int main()
//
//int T;
//scanf("%d", & T);
//int a, b, l, r;
//while (T--)
//
//scanf("%d%d%d%d", & a, & b, & l, & r);
//if (l == r)
//
//cout < < "0.00" < < endl;
//continue;
//
//
//double ly = sqrt(pow(a, 2) - pow(l, 2));
//double ry = sqrt(pow(a, 2) - pow(r, 2));
//double dis = sqrt(pow(l - r, 2) + pow(ly - ry, 2));
//double csita = (2 * pow(a, 2) - pow(dis, 2))*1.0 / (2 * a*a);
//double sita = acos(csita);
//double s1 = a * a*sita / 2;
//double s2 = abs(l)*sqrt(pow(a, 2) - pow(l, 2)) / 2;
//double s3 = abs(r)*sqrt(pow(a, 2) - pow(r, 2)) / 2;
//double s = s1 + s2 + s3;
//s *= 2;
//s = s * (b*1.0 / a);
//printf("%.4lf\\n", s);
//
//

#include"stdafx.h"
#include< iostream>
usingnamespace std;
const double eps = 1e-9;
#pragma warning(disable:4996)
//f函数
double a, b, l, r;
double f(double x)

return sqrt((1 - x * x / (a*a))*(b*b));

//Simpson公式
double simpson(double l, double r)

return (f(l) + 4 * f((l + r) / 2) + f(r))*(r - l) / 6;

double simpson(double l, double r,double all,double eps)

double mid = (l + r) / 2;
double L = simpson(l, mid);
double R = simpson(mid, r);
if (fabs(L + R - all) < = 15 * eps)
return L + R + (L + R - all) / 15;
return simpson(l, mid, L, eps / 2) + simpson(mid, r, R, eps / 2);

double simpson(double l, double r, double eps)

return simpson(l, r, simpson(l, r), eps);

int main()

int T;
scanf("%d", & T);
while (T--)

scanf("%lf%lf%lf%lf", & a, & b, & l, & r);
printf("%.3lf\\n", 2*simpson(l, r,1e-4));

return 0;

上边是我用仿射变换的代码,等我找到BUG了,再把它放出来。



    推荐阅读