zoukankan      html  css  js  c++  java
  • (二分)Codeforces Round #425 (Div. 2) C

    C. Strange Radiation
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    n people are standing on a coordinate axis in points with positive integer coordinates strictly less than 106. For each person we know in which direction (left or right) he is facing, and his maximum speed.

    You can put a bomb in some point with non-negative integer coordinate, and blow it up. At this moment all people will start running with their maximum speed in the direction they are facing. Also, two strange rays will start propagating from the bomb with speed s: one to the right, and one to the left. Of course, the speed s is strictly greater than people's maximum speed.

    The rays are strange because if at any moment the position and the direction of movement of some ray and some person coincide, then the speed of the person immediately increases by the speed of the ray.

    You need to place the bomb is such a point that the minimum time moment in which there is a person that has run through point 0, and there is a person that has run through point 106, is as small as possible. In other words, find the minimum time moment t such that there is a point you can place the bomb to so that at time moment t some person has run through 0, and some person has run through point 106.

    Input

    The first line contains two integers n and s (2 ≤ n ≤ 105, 2 ≤ s ≤ 106) — the number of people and the rays' speed.

    The next n lines contain the description of people. The i-th of these lines contains three integers xi, vi and ti (0 < xi < 106, 1 ≤ vi < s, 1 ≤ ti ≤ 2) — the coordinate of the i-th person on the line, his maximum speed and the direction he will run to (1 is to the left, i.e. in the direction of coordinate decrease, 2 is to the right, i.e. in the direction of coordinate increase), respectively.

    It is guaranteed that the points 0 and 106 will be reached independently of the bomb's position.

    Output

    Print the minimum time needed for both points 0 and 106 to be reached.

    Your answer is considered correct if its absolute or relative error doesn't exceed 10 - 6. Namely, if your answer is a, and the jury's answer is b, then your answer is accepted, if .

    Examples
    Input
    2 999
    400000 1 2
    500000 1 1
    Output
    500000.000000000000000000000000000000
    Input
    2 1000
    400000 500 1
    600000 500 2
    Output
    400.000000000000000000000000000000
    Note

    In the first example, it is optimal to place the bomb at a point with a coordinate of 400000. Then at time 0, the speed of the first person becomes 1000 and he reaches the point 106 at the time 600. The bomb will not affect on the second person, and he will reach the 0 point at the time 500000.

    In the second example, it is optimal to place the bomb at the point 500000. The rays will catch up with both people at the time 200. At this time moment, the first is at the point with a coordinate of 300000, and the second is at the point with a coordinate of 700000. Their speed will become 1500 and at the time 400 they will simultaneously run through points 0 and 106.

    对时间进行二分。check函数的描述方法为:用两个区间分别记录存在人向左、向右能在规定时间内到达的炸弹范围。如果两个范围有交集则当前时间可行,不然不可行。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <queue>
     8 #include <set>
     9 #include <map>
    10 #include <list>
    11 #include <vector>
    12 #include <stack>
    13 #define mp make_pair
    14 //#define P make_pair
    15 #define MIN(a,b) (a>b?b:a)
    16 //#define MAX(a,b) (a>b?a:b)
    17 typedef long long ll;
    18 typedef unsigned long long ull;
    19 const int MAX=1e5+5;
    20 const int INF=1e8+5;
    21 using namespace std;
    22 //const int MOD=1e9+7;
    23 typedef pair<ll,int> pii;
    24 const double eps=0.00000001;
    25 struct person
    26 {
    27     int lo,v,dir;
    28 }a[MAX];//结构体记录一个人初始位置,速度大小,方向
    29 int n,s;
    30 bool check(double limit)//检查在limit的时间范围内是否能达成要求
    31 {
    32     bool left,right;//标记是否可以到达左侧、右侧
    33     left=right=false;//默认不可行
    34     ll left_l=(ll)1e6,left_r=0,right_l=(ll)1e6,right_r=0;//为使存在人向左、向右能到达的炸弹区间
    35     for(int i=1;i<=n;i++)
    36     {
    37         if(a[i].dir==1)//若向左走
    38         {
    39             double pos=(double)a[i].lo-(a[i].v+s)*limit;//最好情况,炸弹就设置在这个位置
    40             if(pos>0.0)
    41                 continue;
    42             left=true;//只为了可以在规定时间内存在到达左侧的人是可能的
    43             pos=(double)a[i].lo-a[i].v*limit;//最坏情况,光速一点作用都未起
    44             if(pos<=0.0)//若最坏情况亦可以满足
    45             {
    46                 left_l=0;left_r=(int)1e6;//炸弹可以随便放
    47                 continue;
    48             }
    49             double min_time=(double)(a[i].lo-limit*a[i].v)/s;//最少需要有多少时间有光速的加成
    50             ll lo=a[i].lo+floor((limit-min_time)*(s-a[i].v));//这种情况下炸弹最右的位置
    51             left_l=min(left_l,(ll)(a[i].lo));
    52             left_r=max(left_r,lo);
    53         }
    54         else//向右走同理
    55         {
    56             double pos=(double)a[i].lo+(a[i].v+s)*limit;
    57             if(pos<1e6)
    58                 continue;
    59             right=true;
    60             pos=(double)a[i].lo+a[i].v*limit;
    61             if(pos>=1e6)
    62             {
    63                 right_l=0;right_r=1e6;continue;
    64             }
    65             double min_time=(double)(1e6-a[i].lo-a[i].v*limit)/s;
    66             ll lo=a[i].lo-floor((limit-min_time)*(s-a[i].v));
    67             right_l=min(right_l,lo);
    68             right_r=max(right_r,(ll)a[i].lo);
    69         }
    70     }
    71     if(!left||!right)//向左或向右有一个到不了
    72         return false;
    73     if((left_l>left_r)||(right_l>right_r))
    74         return false;
    75     return !(left_l>right_r||right_l>left_r);//两者之间有交集
    76 
    77 }
    78 int main()
    79 {
    80     scanf("%d%d",&n,&s);
    81     for(int i=1;i<=n;i++)
    82         scanf("%d%d%d",&a[i].lo,&a[i].v,&a[i].dir);
    83     double l=0.0,r=1e6,mid,an;
    84     for(int i=1;i<=50;i++)
    85     {
    86         mid=(l+r)/2.0;
    87         if(check(mid))
    88             r=an=mid;
    89         else
    90             l=mid;
    91     }
    92     printf("%.7f
    ",an);
    93 }
  • 相关阅读:
    [USACO4.2]草地排水Drainage Ditches
    bzoj3236:[AHOI2013]作业
    小A买彩票-(组合数)
    CSS样式整理大全
    P1880 [NOI1995]石子合并-(环形区间dp)
    P1147连续自然数和-(尺取法)
    POJ2456Aggressive cows-(二分判定)
    NYOJ737石子合并(二)-(区间dp)
    牛客网-乌龟跑步-(dfs)
    int和string之间的转换
  • 原文地址:https://www.cnblogs.com/quintessence/p/7237117.html
Copyright © 2011-2022 走看看