CCF201812-2-小明放学

原题描述

CCF201812-2-小明放学

题目大意:

给出一组数据,表示小明放学的时刻红绿灯初始的状态以及通过每段路程时间。那么小明在回去的路上,红绿灯的状态是随着时间不断变化的。要点是找出小明到达这个红绿灯时该红绿灯的状态

注意点

  1. 给出的测试点最后结果会超过10^9,所以存储最后结果的类型应该使用long long;
  2. 红绿灯的跳变顺序为:红灯(1)–>绿灯(3)–>黄灯(2)–>红灯(1)的循环;
  3. 循环输入可以得到小明在路上已经行走的时间为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;
 }