CCF认证2018122-小明放学

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zee_Chao/article/details/87795288

本人初学,水平有限,若有不足,恳请赐教!

上学问题不同,这里每个路口的状态都是相对于小明离开学校的初始时刻的状态。因此在小明的整个行驶过程中,每个路口的状态也都是动态变化的。因此问题的关键就是要正确地计算小明在行驶到某一个路口时此路口灯的颜色和持续时间。

由于红绿灯的顺序和持续时间存在周期性,故可利用此性质计算小明在到达某个路口时红绿灯的状态。首先,计算整个红绿灯的周期x=r+g+y。不妨令这个周期从红灯开始,则根据顺序可以知道当时间分别在[0,r)、[r,r+g)和[r+g,r+g+y)中时分别表示红绿灯处于红灯、绿灯和黄灯的状态。然后,计算如果此路口初始记录的灯为红、绿和黄则在到达此路口时路灯相对于整个周期工作了多少时间。接着,根据对周期x的取模结果判断其处于[0,r)、[r,r+g)和[r+g,r+g+y)中的哪个时段,从而判断此时灯的颜色。最后,根据上学问题得到的规律来计算通过此路口的时间。

注意:与上学问题不同,放学问题对于数据量的要求更大,因此如果使用int类型存放变量和结果会报错!

具体代码如下:

#include <iostream>

using namespace std;

int main()
{
	long long r, y, g;
	cin >> r >> y >> g;
	long long x = r + y + g; //取红绿灯周期为x
	long long n;
	cin >> n;
	long long sum = 0;
	for(int i = 0; i < n; i++)
	{
		long long k, t;
		cin >> k >> t;
		//假设每个周期的顺序为红、绿、黄,nr、ng和ny分别表示如果此路口初始记录的灯为红、绿和黄
		//则在到达此路口时路灯相对于整个周期工作了多少时间
		//在switch语句中这3个变量至多用到其中一个
		long long nr = (r - t + sum) % x;
		long long ng = (r + g - t + sum) % x;
		long long ny = (r + g + y - t + sum) % x;
		switch(k)
		{
		case 0: //无红绿灯
			sum += t; break;
		case 1: //红灯
			if(0 <= nr && nr < r)
				sum += r - nr;
			else if(r <= nr && nr < r + g)
				sum += 0;
			else
				sum += y - (nr - r - g) + r;
			break;
		case 2: //黄灯
			if(0 <= ny && ny < r)
				sum += r - ny;
			else if(r <= ny && ny < r + g)
				sum += 0;
			else
				sum += y - (ny - r - g) + r;
			break;
		case 3: //绿灯
			if(0 <= ng && ng < r)
				sum += r - ng;
			else if(r <= ng && ng < r + g)
				sum += 0;
			else
				sum += y - (ng - r - g) + r;
		default:break;
		}
	}
	cout << sum;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Zee_Chao/article/details/87795288