题目:http://poj.org/problem?id=3737
我是想练一练三分的,听说这题能用上,但是我做完了也没把三分派上用场(第一种方法)。数学分析一下就能得出结果啊。令圆锥的底面半径是r,高是h,侧面母线是l,由几何知识:圆锥侧面积s1=2*pi*r*l/2=pi*r*l,底面积是s2=pi*r^2。所以s=pi*r*l+pi*r^2. 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 <iostream> #include<cstdio> #include<cmath> using 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; }
#include <iostream> #include<cstdio> #include<cmath> using 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; }