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;
}

 

posted @ 2015-07-17 20:42  陈瑞宇  阅读(486)  评论(0编辑  收藏  举报