关键点:红绿灯处理逻辑
红绿灯逻辑处理部分是本题最关键的一环,它根据小明到达每个红绿灯时的具体情况,决定是否需要等待以及等待多久。
1. 遇到红灯 (k == 1)
- 当前时间在红灯时间内:如果
currentTime(从最近一次红灯开始后经过的时间)小于红灯剩余时间t,则小明需要等待直到红灯结束,等待时间为t - currentTime。 - 当前时间在绿灯时间内:如果
currentTime在t到t + g之间,小明不需要等待,可以直接通过。 - 当前时间在黄灯时间内:如果
currentTime在t + g到t + g + y之间,小明需要等待黄灯结束后再等一个完整的红灯时间,总等待时间为t + g + y - currentTime + r。 - 当前时间再次回到红灯时间:如果
currentTime在t + g + y到t + r + y + g之间,即经过一整轮红绿灯周期后再次遇到红灯,小明需要等待的时间为t + r + y + g - currentTime。
2. 遇到黄灯 (k == 2)
- 当前时间在黄灯时间内:如果
currentTime小于黄灯剩余时间t,则小明需要先等待黄灯结束,再等一个完整的红灯时间,总等待时间为t - currentTime + r。 - 当前时间在红灯时间内:如果
currentTime在t到t + r之间,小明需要等待红灯结束,等待时间为t + r - currentTime。 - 当前时间在绿灯时间内:如果
currentTime在t + r到t + r + g之间,小明可以直接通过,无需等待。 - 当前时间再次回到黄灯时间:如果
currentTime在t + r + g到t + r + y + g之间,即经过一整轮红绿灯周期后再次遇到黄灯,小明需要等待的时间为t + r + y + g - currentTime + r。
3. 遇到绿灯 (k == 3)
- 当前时间在绿灯时间内:如果
currentTime小于绿灯剩余时间t,小明可以直接通过,无需等待。 - 当前时间在黄灯时间内:如果
currentTime在t到t + y之间,小明需要等待黄灯结束后再等一个完整的红灯时间,总等待时间为t + y - currentTime + r。 - 当前时间在红灯时间内:如果
currentTime在t + y到t + y + r之间,小明需要等待红灯结束,等待时间为t + y + r - currentTime。 - 当前时间再次回到绿灯时间:如果
currentTime在t + y + r到t + r + y + g之间,即经过一整轮红绿灯周期后再次遇到绿灯,小明可以直接通过,无需等待。
注意:本部分代码的条件,分支语句有一定程度上的冗余,但是为了理解方便保留了这些冗余,读者可以自行优化。
解题思路
-
初始化和输入: 首先,通过
cin >> r >> y >> g >> n;读入红绿灯的三种状态时间(红、黄、绿灯时间)和小明经过的道路段数(包括红绿灯)。这里r,y,g分别代表红、黄、绿灯持续的时间,n代表总共的路段数。 -
循环处理每个路段: 接下来,对于小明将要经过的每一个路段(包括实际的道路和红绿灯),用一个循环进行处理。在循环中,使用
cin >> k >> t;读入当前路段的类型(k)和耗时或剩余时间(t)。 -
计算时间: 对于每个路段,根据
k的值来判断是实际的道路还是遇到的红绿灯:- 如果
k == 0,表示是一段实际的道路,直接累加该路段的耗时t到timeSpend(总耗时)上。 - 如果
k为1、2、3,则分别表示遇到红灯、黄灯、绿灯,需要根据当前的currentTime(当前时间对红绿灯周期的取余结果)来判断小明到达该灯时的状态,并据此决定是否需要等待。
- 如果
-
红绿灯逻辑处理:
- 对于红灯(
k == 1):如果在红灯时到达,则判断当前时间是否在红灯时间内,如果是,则需等待直到红灯结束;如果当前时间在绿灯或黄灯时间内,则不用等待;若当前时间处于红灯的第二个周期,则同样需要等待。 - 对于黄灯(
k == 2):逻辑类似,只是需要在黄灯结束后等待一个完整的红灯时间。 - 对于绿灯(
k == 3):如果到达时灯是绿的,则无需等待;如果是黄灯或红灯,则需要等待直到绿灯开始。
- 对于红灯(
-
输出结果: 循环结束后,输出
timeSpend,即小明回家所需的总时间。
完整代码
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <stack>
#include <string>
using namespace std;
long long r, y, g, n, k, t, timeSpend, currentTime;
int main()
{
cin >> r >> y >> g >> n;
for (size_t i = 0; i < n; i++)
{
cin >> k >> t;
if (k == 0)
timeSpend += t;
else
{
currentTime = timeSpend % (r + y + g);
if (k == 1) // red light
{
if (0 <= currentTime && currentTime < t) // red
timeSpend += (t - currentTime);
else if (t <= currentTime && currentTime < t + g) {} // green
else if (t + g <= currentTime && currentTime < t + g + y) // yellow
timeSpend += (t + g + y - currentTime + r);
else if (t + g + y <= currentTime && currentTime < t + r + y + g) // red
timeSpend += (t + r + y + g - currentTime);//
}
else if (k == 2) // yellow light;
{
if (0 <= currentTime && currentTime < t) // yellow
timeSpend += (t - currentTime + r);
else if (t <= currentTime && currentTime < t + r) // red
timeSpend += (t + r - currentTime);
else if (t + r <= currentTime && currentTime < t + r + g) {} // green
else if (t + r + g <= currentTime && currentTime < t + r + y + g) // yellow
timeSpend += (t + r + y + g - currentTime + r);
}
else if (k == 3) // green light
{
if (0 <= currentTime && currentTime < t) {} // green // green
else if (t <= currentTime && currentTime < t + y) // yellow
timeSpend += (t + y - currentTime + r);
else if (t + y <= currentTime && currentTime < t + y + r) // red
timeSpend += (t + y + r - currentTime);
else if (t + y + r <= currentTime && currentTime < t + r + y + g) {} // green
}
}
}
cout << timeSpend;
return 0;
}
6044

被折叠的 条评论
为什么被折叠?



