CSP 2018年12月第2题 小明放学
1.思路
-
数据类型 必须要是 long long 类型
所有测试点保证 n ≤ 10^5 可能出现的最大的数为10^ 6 * 10^ 5 = 10^11
int型最大表示的数是2147483647=2*10^9
long long最大存储范围是10^18
-
灯光的顺序 红 -> 绿 -> 黄
k = 1 红 k = 2 黄 k = 3 绿
这个对应顺序有点不一样,因此一定要清楚知道 不同的k 之后灯的变化情况
2.源代码
#include<bits/stdc++.h>
using namespace std;
int r,y,g;
int n;
int k;
int t;
long long Time = 0;
int temp = 0;
int main()
{
cin>>r>>y>>g;
cin>>n;
//int temp = 0;
//for(int i=1;i<=n;i++)
while(n)
{
cin>>k>>t;
if(k==0)
Time+=t;
else if(k==1)
{
temp = Time % (r+y+g);
if(temp<t)
Time += t - temp;
//说明 经过前面的时间,现在是红灯
//且还需要等待 t-temp
else if(temp >=t && (temp<t+g))
Time = Time;
//continue;
//绿灯直接通过
else if(temp >=t+g && (temp<t+g+y))
Time +=t+g+y-temp + r;
//现在是黄灯 等待 t+g+y - temp
//然后等待一个红灯
else if(temp>=t+g+y && (temp<g+y+r))
Time +=t+g+y+ r-temp;
//现在是红灯
//需要等待 t+g+y+r-temp 时间
}
else if(k==2)//黄灯
{
temp = Time % (r+y+g);
if(temp < t)
Time += t-temp+r;
else if(temp>=t &&(temp<t+r))
Time +=t+r - temp;
//红灯 等待 t+r-temp 时间
else if(temp>= t+r &&(temp<t+r+g))
Time = Time;
//continue;
//直接过绿灯
else if(temp>t+r+g && temp<r+g+y)
Time +=t+r+g+y-temp + r;
// !!!!!!
//现在 又到黄灯
//先要等待 t+r+g+y-temp的黄灯时间 ,然后等待一个红灯
}
else if(k==3)
{
temp = Time % (r+y+g);
if(temp<t)
Time = Time;
//continue;
else if(temp>t && temp<t+y)
Time +=t+y-temp+r ;
else if(temp>t+y && temp<t+y+r)
Time +=t+y+r -temp;
else if(temp>t+y+r && temp<y+r+g)
Time = Time;
//continue;
//现在又是绿灯 直接过
}
n--;
}
cout<<Time;
return 0;
}
-
相较于第一题 只需简单分情况即可顺利解决问题
但是这题需要判断 经过前面的时间后,现在对应的灯光情况
temp = Time % (r+y+g);
通过 这个来判断现在相较于一个循环,现在的时间
-
然后通过这个时间来接着判断 与 需要等待时间 t 之间的关系
举例:k==2 且 temp>t+r+g && temp<r+g+y
表示出发时为黄灯,然后 temp的 时间是大于 本来需要等待的时间 t 和经过一个红灯绿灯 的时间
但是又小于 一个整个周期,于是 到达下一个灯光变化(变化为 红灯)
需要等待 t+r+g+y - temp 的时间
并且 下面是红灯 因此还要等待 r 时间
因此最后时间为 Time +=t+r+g+y-temp + r;