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?

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
 
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 1
Sample 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 }

 

 
posted @ 2018-07-21 11:56  王陸  阅读(305)  评论(0编辑  收藏  举报