Official

C - 信号 / Traffic light Editorial by mechanicalpenciI


両方の信号が同時に赤信号から青信号に変わった瞬間を時刻 \(0\) とします。
それぞれの信号は、各非負整数 \(i\) について、時刻 \(0\)\(i\) 秒後から \((i+1)\) 秒後までの間ずっと青信号であるかずっと赤信号であるかのどちらかであり、途中で信号の色はありません。
さらに、信号 \(j\) がその間青であるか赤であるかは、\(i\)\((B_j+R_j)\) で割った余りによって決定することができます。具体的には \(i\)\((B_j+R_j)\) で割った余りが \(B_j\) 未満であれば青信号、\(B_j\) 以上であれば赤信号となります。

よって、各 \(i=0,1,2,\ldots,T-1\) について、それぞれの信号が時刻 \(0\)\(i\) 秒後から \((i+1)\) 秒後までの間何色であるか調べ、ともに青である \(i\) の数が答えとなります。
\(i\) について信号の色は \(O(1)\) で調べることができるため。全体での計算量は \(O(T)\) となります。\(T\leq 10^4\) であるため、十分高速です。 よってこの問題を解くことができました。

c++ による実装例

#include <bits/stdc++.h>
using namespace std;

int main(void){
	int t;
	int b[2],r[2];
	int ans=0;
	cin>>b[0]>>r[0]>>b[1]>>r[1]>>t;
	for(int i=0;i<t;i++){
		if((i%(b[0]+r[0])<b[0])&&(i%(b[1]+r[1])<b[1]))ans++;
	}
	cout<<ans<<endl;
}

posted:
last update: