【CSP试题回顾】201812-2-小明放学

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 <iostream>
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;
}

请添加图片描述

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值