CSP-201812-2-小明放学

解题思路

核心逻辑在于如何处理红绿灯的等待时间。这取决于当前 sumTime 在一个红绿灯周期中的位置以及接下来的路段或红绿灯状态。通过计算当前时间与红绿灯状态的关系,可以确定是否需要等待以及等待多久,从而准确地计算出通过整个路径所需的总时间。

  1. 初始化变量

    • r, y, g 分别表示红灯、黄灯、绿灯的时长。
    • n 表示小明总共经过的道路段数和路过的红绿灯数目。
    • kt 用于读入每一路段或红绿灯的状态和时间。
    • sum_r_y_g 存储一个完整的红绿灯周期的总时长(红+黄+绿)。
    • sumTime 用于累加小明回家所需的总时间。
    • tempTime 用于存储当前时间在红绿灯周期中的位置。
  2. 读入红绿灯设置和路段数量

    • 从输入中读取 r, y, gn
    • 计算 sum_r_y_gr + y + g
  3. 处理每个路段或红绿灯

    • 循环 n 次,每次读入一个 kt
    • 计算 tempTimesumTime % sum_r_y_g,这代表当前时刻在一个红绿灯周期中的位置。
  4. 根据路段或红绿灯类型更新总时间 sumTime

    • 道路段(k=0

      • 对于道路段,因为这里没有红绿灯,所以小明可以直接通过,无需等待。因此,我们只需要将这个道路段的时间(t)加到总时间(sumTime)上。
    • 红灯(k=1

      • 当小明遇到红灯时,他需要等待直到红灯变绿。这里需要判断小明到达红灯时的具体时间。
      • 如果当前总时间(sumTime)在一个红绿灯周期中的位置(tempTime)小于红灯持续时间(t),这意味着小明到达时红灯仍然亮着,所以他需要等待直到红灯结束,也就是再等待 t - tempTime 秒。
      • 另一方面,如果 tempTime 大于红灯和绿灯的总时间(t + g),这意味着当小明到达时,红灯周期已经结束,而下一周期的红灯即将开始。因此,他需要等待直到下一周期的红灯结束,这需要的时间是 t + y + r - tempTime 秒。
    • 黄灯(k=2

      • 遇到黄灯时,小明同样需要等待,直到绿灯亮起。这里的逻辑与遇到红灯时类似,但时间上的计算会根据黄灯和红灯的持续时间进行调整。
      • 如果 tempTime 小于红灯和黄灯持续时间的总和(t + r),这表示小明到达时黄灯正在亮着,他需要等待黄灯和接下来的红灯,总共 t + r - tempTime 秒。
      • 如果 tempTime 大于黄灯、红灯和绿灯的总时长(t + r + g),这表示当前处于一个新的周期,且黄灯即将重新开始,此时他需要等待的时间更长,为 t + r + g + y - tempTime 秒。
    • 绿灯(k=3

      • 当遇到绿灯时,通常情况下小明可以直接通过。但是,如果他到达的时间在绿灯即将结束之后,且黄灯和红灯期间,他需要等待这两个灯的时间再通过。
      • 因此,如果小明到达的时间 tempTime 大于绿灯时间 t,但小于绿灯加黄灯和红灯的时间(t + y + r),他需要等待黄灯和红灯结束,也就是 t + y + r - tempTime 秒。
  5. 输出总时间

    • 循环结束后,输出 sumTime 作为小明回家所需的总时间。

完整代码

#include using namespace std;long long r, y, g, n, k, t, sum_r_y_g, sumTime, tempTime;int main() {cin >> r >> y >> g >> n;sum_r_y_g = r + y + g;for (int i = 0; i < n; i++){cin >> k >> t;tempTime = (sumTime % sum_r_y_g);if (k == 0) sumTime += t;else if (k == 1) //出发时是红灯{if (tempTime < t) sumTime += (t - tempTime); // 等红灯else if (t + g <= tempTime) sumTime += (t + g + y + r - tempTime); // 等黄灯+红灯(防止超过区间)}else if (k == 2) //出发时是黄灯{if (tempTime < t + r) sumTime += (t + r - tempTime); // 等黄+红灯else if (t + g + r <= tempTime) sumTime += (t + r + g + y + r - tempTime);}else if (k == 3) //出发时是绿灯{if (t < tempTime && tempTime <= t + y + r) sumTime += (t + y + r - tempTime); // 等黄+红灯}}cout << sumTime;return 0;}