kmjp's blog

競技プログラミング参加記です

Google Code Jam 2021 Round 1B : A. Broken Clock

AとCがしんどいので、Round1Aで抜けてよかったな…。
https://codingcompetitions.withgoogle.com/codejam/round/0000000000435baf/00000000007ae694

問題

時計の短針・長針・秒針の角度が与えられる。
しかし、3本の針のどれがどれかはわからず、まだ正午の時の各針の初期位置が不明であるとする。
3本の針が指定の角度になる時刻を、ナノ秒単位で求めよ。

解法

まず針の区別がつかない点は、6通り総当たりしよう。
その総当たりの中で、まずはナノ秒の部分を求めよう。
短針が1ナノ秒で1単位角度だけ動く間に長針が12単位角度だけ動くので、両者の角度の差をmod 10^9し、11で割ろう。(11で割り切れない場合、適当にk*10^9を加算する)

あとは秒単位を考えることになるが、これは12時間分12*60*60通りを総当たりし、針の間の角度の差を確認して条件に合うものを探せばよい。

vector<ll> V;
const ll T=1000000000;
const ll T2=120*1000000000LL;
const ll day=360*120*T;

void solve(int _loop) {
	int f,i,j,k,l,x,y;
	V.resize(3);
	cin>>V[0]>>V[1]>>V[2];
	sort(ALL(V));
	
	ll A,B,C,D;
	do {
		ll a;
		FOR(i,11) {
			ll a=i*T+((V[1]-V[0])%T+T)%T;
			if(a%11==0) {
				D=a/11;
				break;
			}
		}
		if(i==12) continue;
		
		A=((V[0]+day-D)%day+day)%day;
		B=((V[1]+day-12*D)%day+day)%day;
		C=((V[2]+day-720*D)%day+day)%day;
		FOR(i,12*60*60) {
			ll a=i*T%day;
			ll b=i*12*T%day;
			ll c=i*720*T%day;
			if((b-a+day)%day!=(B-A+day)%day) continue;
			if((c-b+day)%day!=(C-B+day)%day) continue;
			A=i/3600;
			B=i/60%60;
			C=i%60;
			break;
			
		}
		if(i<12*60*60) break;
		
		
		
		
	} while(next_permutation(ALL(V)));
	_P("Case #%d: %lld %lld %lld %lld\n",_loop,A,B,C,D);
}

まとめ

なんかしんどかった問題。