现在的位置: 首页 > 综合 > 正文

La3485 利用自适应辛普森公式 求积分的和

2013年02月23日 ⁄ 综合 ⁄ 共 1253字 ⁄ 字号 评论关闭
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#include<cstring>
#define maxn 10005
#define INF 0xfffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
using namespace std;
//求积分
double a1;
//Simpson公式中用到的函数
double F(double x)
{
    return sqrt(1+4*a1*a1*x*x);
}
//三点辛普森公式,F是一个全局函数
double simpson(double a,double b)
{
    double c=a+(b-a)/2;
    return (F(a)+4*F(c)+F(b))*(b-a)/6;//(y1+4*y2+y3)*(x2-x1)/3;
}
//自适应Simpson公式(递归过程),极值整个区间[a,b]上的三点Simpson值A
//|S(a,c)+S(c,b)-S(a,b)<=15eps|则返回结果
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);
}
//自适应simpson公式(主过程)
double asr(double a,double b,double eps)
{
    return asr(a,b,eps,simpson(a,b));
}
//用自适应Simpson公式求l=p(w,h)
double get_length(double w,double h)
{
    a1=4.0*h/w/w;//修改a1的值
    return asr(0,w/2,1e-5)*2;
}
int main()
{
    int d,h,b,l,t,tt=1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d",&d,&h,&b,&l);
        if(tt>1)
        printf("\n");
        printf("Case %d:\n",tt++);
        int n=b%d==0?(b/d):(b/d+1);
        double w=1.0*b/n;
        double l1=1.0*l/n;
        double x=0,y=h,z;
        //p(w,h)单调递增
        while(y-x>1e-5)
        {
            z=(x+y)/2;
            if(get_length(w,z)<l1)
            x=z;
            else
            y=z;
        }
        printf("%.2lf\n",h-x);

    }
	return 0;
}

抱歉!评论已关闭.