月度归档: 2019 年 7 月

[CF5D]Follow Traffic Rules 题解

[CF5D]Follow Traffic Rules 题解

题目地址:Codeforces:Problem – 5D – Codeforces、洛谷:CF5D Follow Traffic Rules – 洛谷 | 计算机科学教育新生态

题目描述

Everybody knows that the capital of Berland is connected to Bercouver (the Olympic capital) by a direct road. To improve the road’s traffic capacity, there was placed just one traffic sign, limiting the maximum speed. Traffic signs in Berland are a bit peculiar, because they limit the speed only at that point on the road where they are placed. Right after passing the sign it is allowed to drive at any speed.

It is known that the car of an average Berland citizen has the acceleration (deceleration) speed of a km/h2, and has maximum speed of v km/h. The road has the length of l km, and the speed sign, limiting the speed to w km/h, is placed d km (1 ≤ d < l) away from the capital of Berland. The car has a zero speed at the beginning of the journey. Find the minimum time that an average Berland citizen will need to get from the capital to Bercouver, if he drives at the optimal speed.

The car can enter Bercouver at any speed.

题意简述

你驾驶一辆速度最高为$v$、加速度(加减速)为$a$的汽车,在一条长为$l$的道路上行驶,在距离出发点$d$距离的位置上有一个限速标志,需要以不超过$w$的速度通过它,求不超过限速从起点到终点的最短时间。

输入输出格式

输入格式:
The first line of the input file contains two integer numbers a and v (1 ≤ a, v ≤ 10000). The second line contains three integer numbers l, d and w (2 ≤ l ≤ 10000; 1 ≤ d < l; 1 ≤ w ≤ 10000).

输出格式:
Print the answer with at least five digits after the decimal point.

输入输出样例

输入样例#1:

1 1
2 1 3

输出样例#1:

2.500000000000

输入样例#2:

5 70
200 170 40

输出样例#2:

8.965874696353

题解

高中物理题?我都不知道怎么给这个题加Tag。

首先你需要熟悉这么几个有关匀变速运动的公式:
x-t关系:$x = v_0t + \frac{1}{2} at^2$
x-v关系:$v^2 – v_0^2 = 2ax$
平均速度关系:$x = \frac{v_0 + v}{2} t, t = \frac{v – v_0}{a}$

然后,分情况讨论解决这个问题:

  1. 以加速度$a$加速也无法在$d$距离内加速到$w$速度,或者$w \geq v$怎么样也无法超过限速的情况下,只需要全程加速+匀速即可;
  2. 不满足1的情况即是$d$距离内可以加速到$w$的情况,此时更优的方案是在$d$以前先加速后减速,然后在$d$以后加速+匀速。分加速+减速和加速+匀速$v$+减速两种情况讨论即可。

详细的公式在题解思路里就不写出来了,可以参考代码中应用公式的情况。

代码

// Code by KSkun, 2019/7
#include <cstdio>
#include <cctype>

#include <algorithm>

typedef long long LL;

inline char fgc() {
    static char buf[100000], * p1 = buf, * p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    LL res = 0, neg = 1; char c = fgc();
    for (; !isdigit(c); c = fgc()) if (c == '-') neg = -1;
    for (; isdigit(c); c = fgc()) res = res * 10 + c - '0';
    return res * neg;
}

inline char readsingle() {
    char c;
    while (!isgraph(c = fgc())) {}
    return c;
}

int a, v, l, d, w;

int main() {
    a = readint(); v = readint();
    l = readint(); d = readint(); w = readint();
    double t1 = double(w) / a, t2 = double(v) / a, t3 = double(v - w) / a,
        s1 = w * t1 / 2, s2 = v * t2 / 2, s3 = (w + v) * t3 / 2;
    double ans = 0;
    if(w >= v || s1 >= d) {
        if(s2 >= l) ans += sqrt(2.0 * l / a);
        else {
            ans += t2;
            ans += double(l - s2) / v;
        }
    } else {
        // before d
        if(s2 + s3 <= d) {
            ans += t2 + t3;
            ans += double(d - s2 - s3) / v;
        } else {
            double v0 = sqrt((d - s1) * a + w * w);
            ans += v0 / a + (v0 - w) / a;
        }
        // after d
        if(s3 <= l - d) {
            ans += t3 + (l - d - s3) / v;
        } else {
            double v1 = sqrt(2 * a * (l - d) + w * w);
            ans += (v1 - w) / a;
        }
    }
    printf("%.5lf", ans);
    return 0;
}