主要要注意以下几个点:
1.红绿黄灯的编号和出现顺序,容易绕晕了。。。
2.通过取余来解决当到达当前位置时,会不会已经经过几轮红绿灯的问题。(我之前只是想着可以设置(r+g+y)*n,然后判断n的次数。还是做题做少了)
3.需要考虑,灯剩余的时间t和现在总共花的时间sum之间。如果t>=sum的话,即到了红绿灯的位置,依旧还是原来的状态,那么对于黄灯和红灯,是需要等完目前的时间(那么总时间就是当前红黄灯结束的时间)。t<sum时才需要看进行下面的判断看当前时间处于哪个状态。(我之前没注意到这里,大意了)
4.将红绿黄看成一个整体,而判断当前情况下在哪一个状态,可以看成一个坐标轴比较好理解,以下是一个举例。
(这也就是举例题中给出的例子,输入1 5:当遇到红灯时,出发时还剩5秒,那么就从红灯轴还剩5秒的位置,走上之前的sum值,判断现在在哪个位置,根据坐标轴可以看出此时需要计算在哪个状态需要用30-t+sum=35,根据坐标轴此时就在绿灯位置;
输入2 2:当遇到黄灯时,出发时还剩2秒,那么就从黄灯轴还剩2秒的位置,走上之前的sum值,判断现在在哪个位置,根据坐标轴可以看出此时需要计算在哪个状态需要用3-t+sum=22,根据坐标轴此时就在红灯位置,需要等待的时间呢,就是黄灯+红灯-当前在轴上的位置=11)
注意遇到红绿黄灯时,坐标轴是不一样的噢,我们把从遇到某个灯开始之后的一轮看成一个轴。
这是我根据这种思路写的代码:
#include<iostream>
using namespace std; int main(){ long long r,y,g; scanf("%lld %lld %lld",&r,&y,&g);//红黄绿灯的时间 int n; scanf("%d",&n);//需要处理几段路程 long long sum=0; while(n--){ int k; long long t; scanf("%d %lld",&k,&t); if(k==0){ sum+=t; } else if(k==1){//红灯 if(t>=sum){//原来的灯还没走完 sum=t; } else{ t=((r-t)+sum)%(r+y+g); if(t<r+1){ sum+=(r-t); } else if(t>r+g){ sum=sum+(r+y+g-t)+r; } } } else if(k==2){//黄灯 if(t>=sum){ sum=t+r; } else{ t=((y-t)+sum)%(r+y+g); if(t<r+y+1){ sum=sum+(r+y-t); } } } else if(k==3){//绿灯 if(t>sum){ sum=sum; } else{ t=((g-t)+sum)%(r+y+g); if(t<g+1){ sum=sum; } else{ sum=sum+(r+y+g)-t; } } } } cout<<sum<<endl; return 0; }
原文:https://www.cnblogs.com/lyeeer/p/11442840.html