CCF201812-2-小明放学
原题描述
题目大意:
给出一组数据,表示小明放学的时刻红绿灯初始的状态以及通过每段路程时间。那么小明在回去的路上,红绿灯的状态是随着时间不断变化的。要点是找出小明到达这个红绿灯时该红绿灯的状态
注意点
- 给出的测试点最后结果会超过10^9,所以存储最后结果的类型应该使用long long;
- 红绿灯的跳变顺序为:红灯(1)–>绿灯(3)–>黄灯(2)–>红灯(1)的循环;
- 循环输入可以得到小明在路上已经行走的时间为sum,到达一个红绿灯判断红绿灯状态的方法就是不断消耗累计时间,直到找到一个状态,此时经过x个红绿灯变化之后的值落在红灯,绿灯或者黄灯的时间段内(落在何种灯状态内则需要结果初始输入的值)。
C++程序代码
#include<iostream>
using namespace std;
long long myabs(long long time){
return (time<0)?-time:time;
}
int main(){
long long sum=0,t=0, r,y,g,n,time=0,flag;
int light[4];
cin>>r>>y>>g>>n;
light[0]=0;
light[1]=r;
light[2]=y;
light[3]=g;
//红灯变绿灯变黄灯
for(int i=0;i<n;i++){
cin>>flag>>time;
//如果经过一段路,直接通过
if(flag==0)
sum+=time;
else{
int j=flag;
t=sum%(r+y+g); //经过整数个红绿黄循环回到当前颜色的灯
t=t-time;
j=j-1; //红绿灯跳变一次
if(j<=0) j=3;
//循环减去之前累积的时间并调整红绿灯直到消耗完累计的时间
while(t>=0){
t=t-light[j];
j=j-1; //红绿灯跳变
if(j<=0) j=3;
}
//回退到到达时刻的红绿灯状态
j++;
if(j>=4) j=1;
//j==1则到达时在红灯 ,红灯之后变绿灯
if(j==1){
sum=sum+myabs(t);
}
//j==2则到达时在黄灯需要在加上一个等红灯的时间,绿灯则不计入时间
else if(j==2){
sum=sum+t+myabs(t)+light[1];
}
}
}
cout<<sum<<endl;
return 0;
}