poj3737UmBasketella三分法求极值

来源:互联网 发布:西北师大知行学院几本 编辑:程序博客网 时间:2024/05/01 09:02
 

poj3737UmBasketella三分法求极值

分类: 三分 55人阅读 评论(0) 收藏 举报
三分

题目地址

题目大意:给定一个圆锥体的表面积s,求这个圆锥体的最大体积以及圆锥体体积最大时的底面半径和高。

题目分析:题意十分简单明了。根据圆锥体表面积公式:π * r * r + π * r * l = s(r是底面半径,l是母线长),l = sqrt(h* h + r * r),带入表面积方程可得圆锥高h = sqrt((s/π/r - r)^2 - r * r),根据此式可得一不等式:s/π/r >2r。由此得出底面半径上界为sqrt(s/2π).继续整理方程可得圆锥体体积v = π*sqrt(s^2*r^2/π/π - 2sr^4/π)/3。可以很清楚的看出,圆锥体的体积v是关于圆锥体底面半径的一个2次方程,开口向下,是个凸形图形求极值的问题,很容易想到三分底面半径r。

详情请见代码:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include<cstdio>  
  3. #include<cmath>  
  4.   
  5. using namespace std;  
  6.   
  7. #define eps 1e-8  
  8. #define PI acos(-1.0)  
  9. double s,h,r,v;  
  10.   
  11. double geth(double ra)//求当圆锥底面半径为ra时的高  
  12. {  
  13.     double hi;  
  14.     hi = (s/PI/ra - ra) * (s/PI/ra - ra);  
  15.     hi -= (ra * ra);  
  16.     if(hi < 0)  
  17.         return -1;  
  18.     hi = sqrt(hi);  
  19.     return hi;  
  20. }  
  21.   
  22. int main()  
  23. {  
  24.     while(scanf("%lf",&s) != EOF)  
  25.     {  
  26.         double l,r,midl,midr,v1,v2;  
  27.         l = 0;  
  28.         r = sqrt(s / PI / 2);  
  29.         while(r - l > eps)  
  30.         {  
  31.             midl = (l + r) / 2;  
  32.             midr = (r + midl) / 2;  
  33.             v1 = geth(midl);  
  34.             v2 = geth(midr);  
  35.             v1 = PI * midl * midl * v1 / 3;  
  36.             v2 = PI * midr * midr * v2 / 3;  
  37.             if(v1 > v2)  
  38.                 r = midr;  
  39.             else  
  40.                 l = midl;  
  41.         }  
  42.         printf("%.2lf\n%.2lf\n%.2lf\n",v1,geth(midl),midl);  
  43.     }  
  44.     return 0;  
  45. }  
原创粉丝点击