三分出两个中间的位置即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 两次三分 3 */ 4 #include<stdio.h> 5 #include<string.h> 6 #include<stdlib.h> 7 #include<math.h> 8 #include<algorithm> 9 using namespace std; 10 const int maxn = 105; 11 const double eps = 1e-8; 12 const double pi = acos(-1.0); 13 struct Point { 14 double x,y; 15 }; 16 Point a,b,c,d; 17 double P,Q,R,ans1,ans2; 18 19 double dis( Point aa,Point bb ){ 20 return sqrt( (aa.x-bb.x)*(aa.x-bb.x)+(aa.y-bb.y)*(aa.y-bb.y) ); 21 } 22 23 double GetAns( double tt1,double tt2 ){ 24 double ans; 25 Point temp1,temp2; 26 temp1.x = a.x+tt1*(b.x-a.x),temp1.y = a.y+tt1*(b.y-a.y); 27 temp2.x = c.x+tt2*(d.x-c.x),temp2.y = c.y+tt2*(d.y-c.y); 28 ans = dis( a,temp1 )/P+dis( temp1,temp2 )/R+dis( temp2,d )/Q; 29 return ans; 30 } 31 32 double solve( double x ){ 33 double L,R,mid1,mid2; 34 L = 0; 35 R = 1; 36 while( R-L>eps ){ 37 mid1 = (L+R)/2.0; 38 mid2 = (mid1+R)/2.0; 39 if( GetAns( x,mid1 )<GetAns( x,mid2 ) ){ 40 ans2 = mid1; 41 R = mid2; 42 } 43 else{ 44 ans2 = mid2; 45 L = mid1; 46 } 47 } 48 return GetAns( x,ans2 ); 49 } 50 51 int main(){ 52 int T; 53 scanf("%d",&T); 54 while( T-- ){ 55 scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); 56 scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y); 57 scanf("%lf%lf%lf",&P,&Q,&R); 58 double L,R,mid1,mid2; 59 L = 0; 60 R = 1; 61 while( R-L>eps ){ 62 mid1 = (L+R)/2.0; 63 mid2 = (mid1+R)/2.0; 64 if( solve( mid1 )<solve( mid2 ) ){ 65 ans1 = mid1; 66 R = mid2; 67 } 68 else{ 69 ans1 = mid2; 70 L = mid1; 71 } 72 } 73 printf("%.2lf ",GetAns( ans1,ans2 )); 74 } 75 return 0; 76 }