【CSP CCF记录】201812-2第15次认证 小明放学
题目
样例1输入
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
样例1输出
30 3 30
8
0 10
1 5
0 11
2 2
0 6
0 3
3 10
0 3
思路
参考:CCF小白刷题之路---201812-2 小明放学(C/C++ 100分)_小明放学测试数据-CSDN博客
我们使用一个for循环计算小明通过每段路/每个路灯所需时间。每轮我们需要完成以下几件事:
1. k=0,没有灯直接通过。
2. k=1,2,3,有交通灯,我们需要推测出小明到达时该灯是什么颜色,继而计算出小明在该灯处需要等多久。设小明还有tmp时间到达该灯。
- 小明在到达该灯前,该灯可能已经经历了“红->绿->黄”几轮变化,使用%取余,使tmp限定在最新的周期。
- 若tmp>=t(tmp>t),说明小明到达该灯前,该灯的颜色还会变换,因此需要不断tmp-t,相当于小明不断前进,交通灯颜色不断改变。
- 若tmp<t(tmp<t),说明小明到达该灯前,该灯的颜色已经不会改变了。t-tmp为小明到达该灯时,该灯的持续时间,这时就可以根据灯的颜色分情况讨论。
其他注意点:假设n和r,y,g都是最大取值,这里预计用时就需要采用long long数据类型。
代码
注释还是很详细的。。。
#include<bits/stdc++.h>
using namespace std;
int r,y,g,n;
int main()
{
cin>>r>>y>>g;
cin>>n;
long long ptime=0;//预计用时
for(int i=0;i<n;i++)
{
int k,t;
cin>>k>>t;
int light=k;//标记计算过程中的交通灯颜色
if(light==0)//直通
{
ptime+=t;
//cout<<"ptime:"<<ptime<<endl;
continue;
}
long long tmp=ptime%(r+y+g);//在最新一轮交通灯变换中,小明还有tmp时间到达该路口
//在t时间内交通灯颜色不会变化,tmp>=t说明小明到达路口前交通灯颜色还会变化。
//倒推小明到达路口时交通灯的颜色
while(tmp>=t)
{
tmp=tmp-t;
if(light==1)//当前是红灯
{
t=g;
light=3;//红灯->绿灯
}
else if(light==2)//当前是黄灯
{
t=r;
light=1;//黄灯->红灯
}
else if(light==3)//当前是绿灯
{
t=y;
light=2;//绿灯->黄灯
}
}
//这时tmp<t,说明小明到达路口前交通灯颜色不会再变了,可以讨论小明在路口要等多久
t=t-tmp;
if(light==1)//红灯
{
ptime+=t;
//cout<<"ptime:"<<ptime<<endl;
}
else if(light==2)//黄灯
{
ptime+=(t+r);//等完黄灯后还要再等红灯
//cout<<"ptime:"<<ptime<<endl;
}
//绿灯无需等待直接通过
}
cout<<ptime;
return 0;
}