poj 3737 UmBasketella(数学推导||三分)
题目:V=(pi*r^2)/3*h. 同时有:l^2=r^2+h^2. 由它们可以得到:V=sqrt(s^2*r^2-2*pi*s*r^4)/3. 设f=(3V)^2=s^2*r^2-2*pi*s*r^4. 对它r一阶求导,f'=2sr(s-4pir^2). 当f'=0时,4*pi*r^2=s,此时达到极大值,又h^2=l^2-r^2=[(s-pi*r^2)/(pi*r)]^2-r^2,即h^2=(3/4)^2*s*4/pi-s/4/pi. V的公式也可以化成1/3*s/4*h。
#include #include#includeusing namespace std;const double pi=3.1415926;double r,h,v,s;int main(){ while(cin>>s){ r=sqrt(s/4/pi); h=sqrt(0.75*0.75*4*s/pi-s/(4*pi)); v=s*h/12; printf("%.2lf\n%.2lf\n%.2lf\n",v,h,r); } return 0;}
用三分解决的思路:
针对二次函数或有极值的曲线函数三分搜索,找出那个极值点,最终求出问题的结果。
对比不同mid作为r计算得到的V,不断缩小区间,最后找出极值点,详见代码:
#include #include#includeusing namespace std;const double pi=acos(-1.0);double s;double cal(double r){ double l=(s-pi*r*r)/pi/r; double h=sqrt(l*l-r*r); double v=pi*r*r*h/3; return v;}double ternarysearch(double low,double high){ while(high-low>1e-7){ double mid1=low+(high-low)/3,mid2=high-(high-low)/3; double v1=cal(mid1),v2=cal(mid2); if(v2-v1>1e-9)low=mid1; else high=mid2; } return low;}int main(){ while(cin>>s){ double r,h,l,v; r=ternarysearch(0,sqrt(s/pi)); l=(s-pi*r*r)/pi/r; h=sqrt(l*l-r*r); v=pi*r*r*h/3; printf("%.2lf\n%.2lf\n%.2lf\n",v,h,r); } return 0;}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~