分析小明放学从40分到60分到100分的过程。
实现过程
这里我直接正常按顺序写的代码,首先记录下红绿黄等经过一个轮回所需要的时间
-
如果输入为0直接加在time 上不需要判断。
-
如果输入为3表示目前在绿灯,并且还有t的时间绿灯结束,所以需要判断它前面所用的时间经过多个红绿灯轮回以后时间停在哪,如果仍处于绿灯区域就可以直接走,这里出现40分的问题
如果时间超过了绿灯所剩倒计时,就需要判断:- 如果它超出的时间还不到下一次绿灯到来的时间,就要加上还需要的能到绿灯时候的时间(这个自己画图很容易算出来)
- 但是如果它超出了下一次绿灯到来的时间(说明下一轮的绿灯已经到了)这里就不需要进行处理了。(我就少加了这个判断导致只有40分)
if(temp>t&&temp<t+a[1]+a[2]){//这里一定要加上后面那一句temp<t+a[1]+a[2] time+=(a[1]+a[2]-temp+t); }
举个例子:
如果开始时绿灯还剩10,红灯黄灯绿灯所用时间分别为30,3,30,目前时刻已经到了45,那实际上我到达该路口时是绿灯且倒计时为28,我就可以直接走。
-
接下来如果输入为1或者2我就先算出它到出现绿灯所需要的时间, 如果所需要的时间大于到达时的时间,就需要加上等待的时间,而如果到达时的时间已经超过了这一轮的红绿灯的时间,那么就得计算到达下一轮绿灯的时间。
if(temp<need) time+=(need-temp);
else if(temp>need+a[3]) time+=(all_time-temp+need);
- 然后从60分到100分的原因就只是在存储总共所需要的时间的时候int型数据不够,要使用long long 型
满分代码
#include<iostream>
using namespace std;
typedef long long ll;
main(){
int a[4]={0};
int all_time=0;
// 注意灯亮的顺序是红绿黄
for(int i=1;i<4;i++) {
cin>>a[i];
all_time+=a[i];
}
int n;
cin>>n;
ll time=0;
for(int i=0;i<n;i++){
int k,t;
cin>>k>>t;
if(k==0) time+=t;
else if(k==3){
//表示绿灯还剩多少秒
int temp=time%all_time;
// 小于的时候直接就可以过
if(temp>t&&temp<t+a[1]+a[2]){//这里一定要加上后面那一句temp<t+a[1]+a[2],因为这里如果它大于的话相当于到了下一轮绿灯,直接就可以过
time+=(a[1]+a[2]-temp+t);
}
}
else {
int temp=time%all_time;
// 计算到绿灯所需要的时间
int need=0;
if(k==1) need=t;
else if(k==2) need=t+a[1];
if(temp<need) time+=(need-temp);
//如果到达时已经超过了这轮绿灯只能等下一轮(肯定不可能超过下一轮绿灯,这里已经对一轮绿灯所需时间取余了)
else if(temp>need+a[3]) time+=(all_time-temp+need);
}
}
cout<<time<<endl;
}