思路
(我怕不是个废物,交通规则都不懂,写了一个小时一直WA,后来发现自己把交通规则搞错了,又更:刚刚才发现小明上学题目里详细写了交通规则,怪自己先做了小明放学的题目)
红绿灯的循环顺序为绿黄红,也可以写成黄红绿、红绿黄,写成绿黄红比较方便。
每次循环以刚跳到绿灯时刻为
0
0
0时刻,所以举例:假设绿灯持续
30
30
30秒、黄灯
3
3
3秒、红灯
30
30
30秒时,第
18
18
18秒是绿灯,第
31
31
31秒是黄灯,第
54
54
54秒是红灯,第
83
≡
20
m
o
d
(
30
+
3
+
30
)
83\equiv 20\mod(30+3+30)
83≡20mod(30+3+30)秒是绿灯,依次类推。
在每一个红绿灯路口,以出发时刻的那一轮中刚跳到绿灯的时刻为
0
0
0时刻,比如,假设绿灯持续
30
30
30秒、黄灯
3
3
3秒、红灯
30
30
30秒,在某一路口得到如题目所述中的
k
=
2
,
t
=
2
k=2, t=2
k=2,t=2(出发时刻),说明,此时是在黄灯快要结束
2
2
2秒的时刻,说明出发时刻为第
31
31
31时刻(
30
+
3
−
2
=
31
30+3-2=31
30+3−2=31),在新到达的路口处,出发时刻加上在路途中耗费的时间也就是到达该路口的时刻(可能会大于
g
+
y
+
r
g+y+r
g+y+r之和),该时刻对
g
+
y
+
r
g+y+r
g+y+r取余即是在绿黄红一轮中相对绿灯刚开始的具体时刻,记为
n
o
w
now
now,比如上述中的
83
83
83时刻是该轮中的第
20
20
20时刻,即
n
o
w
=
20
now=20
now=20,可以根据这一时刻判断当前红绿灯的状态,如果是绿灯,直接通行,否则,已知等到绿灯为止(即等待时间为
g
+
y
+
r
−
n
o
w
g+y+r-now
g+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;
}