• 【BZOJ1857】【SCOI2010】传送带 [三分]


    传送带

    Time Limit: 1 Sec  Memory Limit: 64 MB
    [Submit][Status][Discuss]

    Description

      在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间

    Input

      输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整数,表示C和D的坐标,分别为Cx,Cy,Dx,Dy 第三行是3个整数,分别是P,Q,R

    Output

      输出数据为一行,表示lxhgww从A点走到D点的最短时间,保留到小数点后2位

    Sample Input

      0 0 0 100
      100 0 100 100
      2 2 1

    Sample Output

      136.60

    HINT

      对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
      1<=P,Q,R<=10

    Main idea

      给定平面上的两条线段AB,CD,在AB,CD上移动会有一个特别的速度,在平面上移动会有一个速度,求从点A到点D的最短时间。

    Solution

      首先发现坐标范围-1000~1000,并且精度要求不高,从此基础上思考。我们先考虑从AB上一个定点O到CD上的距离,发现其中从O到CD的距离是先减小再增大的,我们大胆猜测这道题的答案满足单峰性。然后我们可以用三分(效率为O(log1.5(n)))来实现。
      我们现在可以求出一个定点求CD的最短时间,这里用三分实现。然后怎么办呢?
      由于AB也是一条线段,我们大胆猜测,可以再在AB上三分一个点,这样就是三分套三分,最后发现其正确性可以证明。
      三分方法(这里给出求最小值的方法):在区间1/3处和2/3处各取两个点l,r,如果左段(即L~l)的答案比右段(r~R)的更优,那么由于单峰性(图像类似一个抛物线)可以抹去右段,多次操作使得答案最优。

    Code

     1 #include<iostream>  
     2 #include<algorithm>  
     3 #include<cstdio>  
     4 #include<cstring>  
     5 #include<cstdlib>  
     6 #include<cmath>
     7 #include<queue>
     8 using namespace std;  
     9       
    10 const int ONE=1005;
    11 const int MOD=19650827;
    12 
    13 int n;
    14 
    15 struct power
    16 {
    17         double x,y;
    18         double AB,CD,PM;
    19         friend power operator +(power a,power b) {a.x=a.x+b.x; a.y=a.y+b.y; return a;}
    20         friend power operator -(power a,power b) {a.x=a.x-b.x; a.y=a.y-b.y; return a;}
    21         
    22 };
    23 power A,B,C,D,v;
    24 power l1,l2,r1,r2;
    25 power a,b;
    26 power pass;
    27 
    28 int get()
    29 {
    30         int res,Q=1;    char c;
    31         while( (c=getchar())<48 || c>57)
    32         if(c=='-')Q=-1;
    33         if(Q) res=c-48; 
    34         while((c=getchar())>=48 && c<=57) 
    35         res=res*10+c-48; 
    36         return res*Q; 
    37 }
    38 
    39 double dist(power a,power b)
    40 {
    41         return (double)sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
    42 }
    43 
    44 double Getdist(power E,power F)
    45 {
    46         return dist(A,E)/v.AB + dist(E,F)/v.PM + dist(F,D)/v.CD;
    47 }
    48 
    49 double Trivide(power O)
    50 {
    51         power l=C,r=D,pass,a,b;
    52         while(dist(l,r)>0.001)
    53         {
    54             pass.x=(r.x-l.x)/3.0;    pass.y=(r.y-l.y)/3.0;
    55             a=l+pass;    b=r-pass;
    56             if(Getdist(O,a) < Getdist(O,b)) r=b;
    57             else l=a;
    58         }
    59         return Getdist(O,l);
    60 }
    61 
    62 int main()
    63 {
    64         scanf("%lf %lf %lf %lf",&A.x,&A.y,&B.x,&B.y);
    65         scanf("%lf %lf %lf %lf",&C.x,&C.y,&D.x,&D.y);
    66         scanf("%lf %lf %lf",&v.AB,&v.CD,&v.PM);    
    67         
    68         power l=A,r=B;
    69         while(dist(l,r)>0.001)
    70         {
    71             pass.x=(r.x-l.x)/3.0;    pass.y=(r.y-l.y)/3.0;
    72             a=l+pass;    b=r-pass;
    73             if(Trivide(a) < Trivide(b)) r=b;
    74             else l=a;
    75         }
    76         
    77         printf("%.2lf",Trivide(l));
    78 }
    View Code
  • 相关阅读:
    leetcode刷题笔记303题 区域和检索
    leetcode刷题笔记301题 删除无效的括号
    20201208日报
    20201118日报
    20201117日报
    20201116日报
    20201115日报
    20201114日报
    20201113日报
    20201112日报
  • 原文地址:https://www.cnblogs.com/BearChild/p/6441257.html
Copyright © 2020-2023  润新知