1 /*LA4986 2 三分法求出凹性函数最小值: 3 三分法本身的写法不难,这道题的关键是数学: 4 1、找到表示量h,找到r与h的唯一确定关系,进而确定了h,就确定了相应的v 5 2、判断出v(h)是一个凹性函数。因为r受离散的点的影响,无法从列函数,确定凹性。 6 我也仅仅是从极限的思想上考虑的。当h无限小,由(0,0,h)连向点p的直线越平,r趋向于无穷; 7 当h无限大时,r的增长速度更不上h,h趋向于无穷。 8 3、故v(h)的两边是无限增大的 9 */ 10 #include<iostream> 11 #include<stdio.h> 12 #include<string.h> 13 #include<algorithm> 14 #include<stdlib.h> 15 #include<math.h> 16 #include<queue> 17 #include<vector> 18 #include<map> 19 #define LL long long 20 21 using namespace std; 22 23 int n; 24 double a[10005],b[10005],c[10005],minH; 25 26 double GetR(double H) 27 { 28 double mr=sqrt(a[1]*a[1]+b[1]*b[1])*H/(H-c[1]); 29 for(int i=2;i<=n;i++) 30 mr=max(mr,sqrt(a[i]*a[i]+b[i]*b[i])*H/(H-c[i])); 31 return mr; 32 } 33 double F(double H)//返回的是由h确定的r,进而确定的V 34 { 35 double mr=GetR(H); 36 return M_PI/3*mr*mr*H; 37 } 38 void solve() 39 { 40 double L=minH,R=10000000; 41 while(L+1e-7<R) 42 { 43 double m1=L+(R-L)/3; 44 double m2=R-(R-L)/3; 45 double Fm1,Fm2; 46 Fm1=F(m1);Fm2=F(m2); 47 // cout<<"L="<<L<<","<<"R="<<R<<endl; 48 if (Fm1<=Fm2) R=m2;else L=m1; 49 } 50 printf("%.3lf %.3lf ",L,GetR(L)); 51 52 } 53 int main() 54 { 55 while(cin>>n) 56 { 57 minH=1e-8; 58 for(int i=1;i<=n;i++) { 59 cin>>a[i]>>b[i]>>c[i]; 60 minH=max(minH,c[i]); 61 } 62 solve(); 63 } 64 return 0; 65 }