HDU 1724 Ellipse (自适应辛普森公式)

自适应simpson裸题


自适应辛普森:


simpson公式这样估计一段积分的值:对于F函数,a到b这一段的积分近似等于S(period)=(F(a)+F(b)+4*F(mid))/6*(b-a),即认为近似为一个常数积分,常数等于(F(a)+F(b)+4*F(mid))/6,其中mid=(b-a)/2。

如果F函数波动剧烈,这个估计方法会很不准。所以自适应辛普森会自动在波动大的地方对区间分隔的更细,在进行估计。

判断方法:设将当前区间P分为L,R两个区间,若fabs(S(L)+S(R)-S(P))>15*eps,则需要重新细分。


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

int aa,bb;

double F(double x){
	return sqrt(bb*bb-x*x*bb*bb/(aa*aa));
}

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

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)<=15*eps) 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--){
		int l,r;
		scanf("%d%d%d%d",&aa,&bb,&l,&r);
		printf("%.3f\n",asr(l,r,1e-6)*2);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值