思路
(我怕不是个废物,交通规则都不懂,写了一个小时一直WA,后来发现自己把交通规则搞错了,又更:刚刚才发现小明上学题目里详细写了交通规则,怪自己先做了小明放学的题目)
红绿灯的循环顺序为绿黄红,也可以写成黄红绿、红绿黄,写成绿黄红比较方便。
每次循环以刚跳到绿灯时刻为000时刻,所以举例:假设绿灯持续303030秒、黄灯333秒、红灯303030秒时,第181818秒是绿灯,第313131秒是黄灯,第545454秒是红灯,第83≡20mod (30+3+30)83\equiv 20\mod(30+3+30)83≡20mod(30+3+30)秒是绿灯,依次类推。
在每一个红绿灯路口,以出发时刻的那一轮中刚跳到绿灯的时刻为000时刻,比如,假设绿灯持续303030秒、黄灯333秒、红灯303030秒,在某一路口得到如题目所述中的k=2,t=2k=2, t=2k=2,t=2(出发时刻),说明,此时是在黄灯快要结束222秒的时刻,说明出发时刻为第313131时刻(30+3−2=3130+3-2=3130+3−2=31),在新到达的路口处,出发时刻加上在路途中耗费的时间也就是到达该路口的时刻(可能会大于g+y+rg+y+rg+y+r之和),该时刻对g+y+rg+y+rg+y+r取余即是在绿黄红一轮中相对绿灯刚开始的具体时刻,记为nownownow,比如上述中的838383时刻是该轮中的第202020时刻,即now=20now=20now=20,可以根据这一时刻判断当前红绿灯的状态,如果是绿灯,直接通行,否则,已知等到绿灯为止(即等待时间为g+y+r−nowg+y+r-nowg+y+r−now)。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL ans, k, t, r, y, g, n, tot, now;
int main() {
scanf("%lld %lld %lld %lld", &r, &y, &g, &n);
tot = r + y + g;
for(int i = 1; i <= n; i++) {
scanf("%lld %lld", &k, &t);
if(0 == k) ans += t;
else {
if(1 == k) now = g + y + r - t + ans;
else if(2 == k) now = g + y - t + ans;
else now = g - t + ans;
now = now % tot;
if(now >= g) ans += tot - now;
}
}
printf("%lld", ans);
return 0;
}