zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    68     }
    69     return 0;
    70 }
    
    
    
     
  • 相关阅读:
    redis常用数据类型与命令
    bcb6重启应用程序
    MySQL 关联查询  外连接 { LEFT| RIGHT } JOIN
    MySQL 关联查询 内连接
    MySql子查询
    MySql单表查询
    表级操作语句
    库级操作语句
    14.正则表达式、re模块、元字符
    13.生成器、迭代器、 模块、包和包管理
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/9346163.html
Copyright © 2011-2022 走看看