UVA 12905 Volume of Revolution (几何,微积分)

题意:分段用椎台面积近似计算体积,然后计算出近似值和真实值的相对误差

微积分加数学。

平头椎台的体积计算公式:

V = 1/3*h*(S1+S2*sqrt(S1*S2)

一个更快的计算多项式值的方法,来自豪爷,算法是for(int i = 15; i >= 0; i--) ans += ans*x+p[i],比直接pow快了一倍

#include<cstdio>

#include<cmath>

#include<cstring>

const double pi = atan(1)*4;



int poly[8],Q[16],n;



inline double calR(double x)

{

    double ans = poly[0];

    for(int i = 1; i <= n; i++ ){

        ans += poly[i]*pow(x,i);

    }

    return ans;

}



inline double calint(int x){

    double ans = 0;

    for(int i = 0,sz = n<<1; i <= sz; i++ ){

        ans += Q[i]*pow(x,i+1)/(i+1);

    }

    return ans;

}



inline double calV(int a,int b){

    memset(Q,0,sizeof(Q));

    for(int i = 0; i <= n; i++){

        for(int j = 0; j <= n; j++)

            Q[i+j] += poly[i]*poly[j];

    }



    return (calint(b)-calint(a))*pi;

}



inline double calS(double R,double theta,int slices){

    return R*sin(theta)/2*R*slices;

}



int main()

{



    int T;

    scanf("%d",&T);

    int cas = 0;

    while(T--){

        memset(poly,0,sizeof(poly));

        scanf("%d",&n);

        for(int i = n; i >= 0;i--)

            scanf("%d",poly+i);

        int a,b;

        scanf("%d%d",&a,&b);

        int slices,stacks;

        scanf("%d%d",&slices,&stacks);

        double dx = (b-a)*1.0/stacks, dtheta = 2*pi/slices;

        double R1 = calR(a),S1 = calS(R1,dtheta,slices);



        double x = a+dx;



        double ape = 0;

        for(int i = 0; i < stacks; i++){

            double R2 = calR(x);

            double S2 = calS(R2,dtheta,slices);

            double dS = dx/3*(S1+S2+sqrt(S1*S2));

            ape += dS;

            x += dx;

            R1 = R2; S1 =S2;

        }

        double vol = calV(a,b);



        printf("Case %d: %.4lf\n",++cas,fabs(ape-vol)/vol*100);

    }

    return 0;

}

 

你可能感兴趣的:(uva)