Line belt(三分镶嵌)
In a two-dimensional plane there are two line belts, there are two segments AB and CD, lxhgww's speed on AB is P and on CD is Q, he can move with the speed R on other area on the plane.
How long must he take to travel from A to D?
How long must he take to travel from A to D?
Input
The first line is the case number T.
For each case, there are three lines.
The first line, four integers, the coordinates of A and B: Ax Ay Bx By.
The second line , four integers, the coordinates of C and D:Cx Cy Dx Dy.
The third line, three integers, P Q R.
0<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
For each case, there are three lines.
The first line, four integers, the coordinates of A and B: Ax Ay Bx By.
The second line , four integers, the coordinates of C and D:Cx Cy Dx Dy.
The third line, three integers, P Q R.
0<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
Output
The minimum time to travel from A to D, round to two decimals.
Sample Input
1 0 0 0 100 100 0 100 100 2 2 1Sample Output
136.60
题目意思:就是给你两条线段AB , CD的坐标 ,一个人在AB以速度p跑,在CD上以q跑,在其他地方跑速度是r,问你从A到D最少的时间。
解题思路:设E在AB上,F在CD上。 则人在线段AB上花的时间为:f = AE / p
,人走完Z和Y所花的时间为:g= EF / r + FD / q
。
f函数是一个单调递增的函数,而g很明显是一个先递减后递增的函数。两个函数叠加,所得的函数应该也是一个先递减后递增的函数。这算是一道三分又三分的题目,可以看成是三分的镶嵌,
先对AB上的位置E进行三分枚举,每一次枚举的时候把E看做定点,在这种情况下,再对CD上的位置F进行三分枚举,这样可以求出此次三分AB的最小时间。然后完成对AB的三分后,就会得到从A到D的最短时间。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 #define EPS 1e-8 8 struct Point 9 { 10 double x; 11 double y; 12 } a, b, c, d, e, f; 13 double p, q, r; 14 double dis(Point p1, Point p2)///两点之间的距离 15 { 16 return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); 17 } 18 double calc(double alpha)///alpha代表在f点在cd中位置的比率 19 { 20 f.x = c.x + (d.x - c.x) * alpha; 21 f.y = c.y + (d.y - c.y) * alpha; 22 return dis(f, d) / q + dis(e, f) / r;///返回在ef和fd上花费的时间 23 } 24 double inter_tri(double alpha)///在f点进行三分 25 { 26 double l = 0.0, r = 1.0, mid, mmid, cost; 27 e.x = a.x + (b.x - a.x) * alpha; 28 e.y = a.y + (b.y - a.y) * alpha;///e点在线段ab中的位置 29 while (r - l > EPS) 30 { 31 mid = (l + r) / 2; 32 mmid = (mid + r) / 2; 33 cost = calc(mid); 34 if (cost <= calc(mmid)) 35 r = mmid; 36 else 37 l = mid; 38 } 39 return dis(a, e) / p + cost; 40 } 41 double solve()///在e点进行三分 42 { 43 double l = 0.0, r = 1.0, mid, mmid, ret; 44 while (r - l > EPS) 45 { 46 mid = (l + r) / 2; 47 mmid = (mid + r) / 2; 48 ret = inter_tri(mid); 49 if (ret <= inter_tri(mmid)) 50 r = mmid; 51 else 52 l = mid; 53 } 54 return ret; 55 } 56 int main() 57 { 58 int T; 59 double ans; 60 scanf("%d",&T); 61 while(T--) 62 { 63 scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); 64 scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y); 65 scanf("%lf%lf%lf",&p,&q,&r); 66 ans=solve(); 67 printf("%.2lf\n",ans); 68 } 69 return 0; 70 }