# CF5D Follow Traffic Rules
[题目传送门](https://www.luogu.com.cn/problem/CF5D) | [更好的阅读体验](https://www.luogu.com.cn/blog/cxy-xlf-1003/solution-cf5d)
## 题意
给你一个车的最大速度 $v$、加速度 $a$(加速或者刹车都是这个加速度)、路程 $l$,其中 $d$ 处有一个测速点速度不能超过 $w$。问:从速度为 $0$ 开始最快要多久能通过终点?
## 分析
一道运动学物理题……
#### 主要思路
根据给定的加速度、最大速度、目标位置、初始位置和限制速度,计算汽车从初始位置加速到目标位置的最短时间。为了实现这个目标,代码首先计算了在不同阶段的加速、匀速和减速过程中,汽车行驶的时间和距离。
代码的思路可以分为以下几个步骤:
1. 输入数据:首先通过 `scanf` 函数从标准输入中读取加速度 ($aa$)、最大速度 ($vv$)、目标位置 ($ll$)、初始位置 ($dd$) 和限制速度 ($ww$)。这些数据将在后续计算中使用。
2. 转换数据类型:将输入的整数值转换为 `double` 类型,以便进行精确的浮点数计算。
3. 计算时间和距离:
- 计算从初始速度加速到最大速度所需的时间 $t1$ 和距离 $x1$。
- 计算从初始速度加速到限制速度所需的时间 $t2$ 和距离 $x2$。
- 计算从限制速度减速到最大速度所需的时间 $t3$ 和距离 $x3$。
4. 根据不同情况输出最短时间:
- 如果最大速度小于等于限制速度 ($v \le w$),分两种情况讨论:
- 如果加速到最大速度的距离大于等于目标位置 ($x1 \ge l$),则输出加速到最大速度所需的时间
$$\sqrt{(l*2.0/a)}$$
- 否则,输出加速到最大速度并匀速行驶到目标位置所需的时间
$$t1 + (l - x1) \div v$$
- 如果最大速度大于限制速度 ($v > w$),分三种情况讨论:
- 如果从初始位置一直加速到匀速的距离小于等于限制速度行驶的距离 ($d \le x2$),则执行与上述情况相同的操作。
- 如果从初始位置加速到限制速度再减速到最大速度的距离小于等于限制速度行驶的距离 ($d \le x1 + x3$),则根据两段加速和减速过程的时间和距离,输出最短时间。
- 否则,即在加速到最大速度并匀速行驶到限制速度再减速到最大速度的距离大于限制速度行驶的距离的情况,根据两段加速和减速过程的时间和距离,输出最短时间。
这样,代码通过计算不同情况下的最短时间,找到了汽车从初始位置加速到目标位置的最短时间,并输出了结果。这个算法的复杂度是 $O(1)$。
## AC Code
```C++
#include <bits/stdc++.h> // 保命万能头
using namespace std;
int main()
{
int aa, vv, ll, dd, ww; //加速度、最大速度、目标位置、初始位置和限制速度
scanf("%d%d%d%d%d", &aa, &vv, &ll, &dd, &ww); // 从标准输入读取五个值
// 将输入转换为浮点数,以便后续计算
double a = aa, v = vv, l = ll, d = dd, w = ww;
// 计算从初始速度加速到最大速度所需的时间和距离
double t1 = v / a;
double x1 = 0.5 * a * t1 * t1;
// 计算从初始速度加速到限制速度所需的时间和距离
double t2 = w / a;
double x2 = 0.5 * a * t2 * t2;
// 计算从限制速度减速到最大速度所需的时间和距离
double t3 = (v - w) / a;
double x3 = w * t3 + 0.5 * a * t3 * t3;
// 判断最大速度是否小于等于限制速度
if (v <= w)
{
// 如果加速到最大速度的距离大于等于目标位置,则输出加速到最大速度所需的时间
if (x1 >= l)
printf("%lf\n", sqrt(l * 2.0 / a)); // 加速到最大速度的时间:sqrt(l * 2.0 / a)
else
// 否则,输出加速到最大速度并匀速行驶到目标位置所需的时间
printf("%lf\n", t1 + (l - x1) / v); // 总时间:t1 + (l - x1) / v
}
else
{
// 如果限制速度行驶的距离小于等于从初始位置一直加速到匀速的距离,则执行与上述情况相同的操作
if (d <= x2)
{
if (x1 >= l)
printf("%lf\n", sqrt(l * 2.0 / a));
else
printf("%lf\n", t1 + (l - x1) / v);
}
else if (d <= x1 + x3) // 否则,如果限制速度行驶的距离小于等于从初始位置加速到限制速度再减速到最大速度的距离
{
double vm1 = sqrt(a * (d - x2) + w * w); // 计算在限制速度下行驶的最大速度
// 如果目标位置距离限制速度减速到最大速度的距离小于等于从限制速度加速到最大速度的距离
if (l - d <= x3)
{
double vm2 = sqrt(2 * a * (l - d) + w * w); // 计算在限制速度下行驶的最大速度
printf("%lf\n", t2 + (vm1 - w) * 2 / a + (vm2 - w) / a); // 输出最短时间:t2 + (vm1 - w) * 2 / a + (vm2 - w) / a
}
else
// 否则,输出在限制速度下加速到最大速度,再减速到目标位置所需的最短时间
printf("%lf\n", t2 + (vm1 - w) * 2 / a + t3 + (l - d - x3) / v); // 总时间:t2 + (vm1 - w) * 2 / a + t3 + (l - d - x3) / v
}
else // 否则,即在加速到最大速度并匀速行驶到限制速度再减速到最大速度的距离大于限制速度行驶的距离的情况
{
// 如果目标位置距离限制速度减速到最大速度的距离小于等于从限制速度加速到最大速度的距离
if (l - d <= x3)
{
double vm2 = sqrt(2 * a * (l - d) + w * w); // 计算在限制速度下行驶的最大速度
printf("%lf\n", t1 + t3 + (d - x1 - x3) / v + (vm2 - w) / a); // 输出最短时间:t1 + t3 + (d - x1 - x3) / v + (vm2 - w) / a
}
else
// 否则,输出在加速到最大速度并匀速行驶到目标位置所需的最短时间
printf("%lf\n", t1 + t3 + (d - x1 - x3) / v + t3 + (l - d - x3) / v); // 总时间:t1 + t3 + (d - x1 - x3) / v + t3 + (l - d - x3) / v
}
}
return 0; // 返回 0 表示程序正常结束
}
//求过
```
_~~**求个赞**~~_