旋转体的体积和表面积

积分公式

令曲线 y=f(x) x 轴旋转,形成的旋转体,则其体积和表面积可以计算积分而得(假设体积和表面积一定存在,积分一定存在,这里不讨论数学问题)。
体积公式为:

V=πy2dx

表面积公式为
S=2πy1+y2dx

剩下的就是推导定积分公式。

ZOJ3866 Cylinder Candy

ZOJ3866,一个圆柱体半径为 r mm,高度为 h mm,外围包裹着 d mm厚的涂层,求其表面积和体积。这个题目要精确到 108 ,推不出积分公式就不用做了。
旋转体的体积和表面积_第1张图片
整个部分最关键的就是四个边角的形状,四个边角合在一起恰好是一个圆环的外半侧。所以关键就是求圆环的外半侧的体积以及表面积。
曲线方程为:

y=r+d2x2,x[d,d]

则,体积积分为:
V=π(r2+d2x2+2rd2x2)dx=π(r2+d2)dxπx2dx+2πrd2x2dx

第3项稍微麻烦一点,其不定积分为:
d2x2dx=12xd2x2+d22arcsinxd+C

表面积公式首先要求 y 的导数:
y=xd2x2

所以,
1+y2=d2d2x2

表面积的积分为:
S=2π(r+d2x2)dd2x2dx=2πrd1d2x2dx+2πddx

第一项就是 arcsinxd+C
所以,体积和表面积全部可以求出原函数的解析式。

然后把其他部分的圆柱体算上即可。

#include 
#include 

double const PI = acos(-1.0);
double const DELTA = 1E-6;
double R,H,D;

double integral(){
    return (2.0*D*R*R+4.0*D*D*D/3.0+D*D*R*PI) * PI;
}

double integral2(){
    return 4.0*PI*D*D + 2.0*PI*PI*R*D;
}

int main(){
    int nofkase;
    scanf("%d",&nofkase);
    while( nofkase-- ){
        scanf("%lf%lf%lf",&R,&H,&D);
        double v = integral() + PI * ( R + D ) * ( R + D ) * H;
        double s = integral2() + 2.0 * PI * ( R + D ) * H + 2.0 * PI * R * R;
        printf("%.12lf %.12lf\n",v,s);
    }
    return 0;
}

ZOJ3898 Stean

ZOJ3898同样是旋转体的表面积和体积。曲线为:

y=2+cosx

不同点在于定积分公式中有一项是得不到解析式的。但是这道题很明显曲线是周期性函数,定积分的周期就是 π ,而题目要求在 102 以内,所以取 ϵ 103 104 直接使用积分定义去计算。每次计算需要迭代的次数在几万次,应该是没有问题的。
体积积分:
V=π(2+cosx)2dx=4πdx+4πcosxdx+πcos2xdx

其中第三项为:
cos2xdx=x2+sin2x4+C

表面积积分:
S=2π(2+cosx)1+sin2xdx=4π1+sin2xdx+2π1+sin2xdsinx

其中第一项不知道积不积得出来,反正我没有积出来。数学不行,就用计算机的方法算。第二项令 t=sinx ,则

1+t2dt=12t1+t2+12lnt+1+t2+C

#include 
#include 

double const PI = acos(-1.);
double const EPS = 1E-4;

//计算一个周期
double init1p(){
    double ret = 0.0;
    for(double x=0.0;x<=0.5*PI;x+=EPS){
        double t = sin(x);
        ret += sqrt(1.0+t*t);
    }
    return 8.0*PI*ret*EPS;
}

double const ONEP = init1p();

double v(double z1,double z2){
    return 4.0 * PI * ( z2 - z1 )
        + 4.0 * PI * ( sin(z2) - sin(z1) )
        + 0.5 * PI * ( z2 - z1 )
        + 0.25 * PI * ( sin(z2+z2) - sin(z1+z1) );
}

double s(double z1,double z2){
    //计算底面积
    double y1 = 2.0 + cos(z1);
    double ret = PI * y1 * y1;

    //计算解析式的积分
    double t2 = sin(z2), t1 = sin(z1);
    double tt2 = sqrt(1.0+t2*t2), tt1 = sqrt(1.0+t1*t1);
    ret += PI * ( t2 * tt2 - t1 * tt1 )
        + PI * ( log(fabs(t2+tt2)) - log(fabs(t1+tt1)) );

    //计算周期
    int n = (int)(( z2 - z1 ) / PI);
    ret += ONEP * (double)n;

    //计算积分
    double tmp = 0.0;
    for(double x=z1+PI*(double)n;x<=z2;x+=EPS){
        double t = sin(x);
        tmp += sqrt(1.0+t*t);
    }
    return ret += tmp * 4.0 * PI * EPS;
}

int main(){
    int kase;
    scanf("%d",&kase);
    while(kase--){
        double z1,z2;
        scanf("%lf%lf",&z1,&z2);
        printf("%.5lf %.5lf\n",v(z1,z2),s(z1,z2));
    }
    return 0;
}

你可能感兴趣的:(ACM/ICPC,ACM其他)