标签:include Dimension travel inpu put desc strong round out
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 }
标签:include Dimension travel inpu put desc strong round out
原文地址:https://www.cnblogs.com/wkfvawl/p/9346163.html