Google Code Jam Qualification Round 2010
Google Code Jam Qualification Round 2010に参加した。3問とも通ったらしい。
A. Snapper Chain
結局、T-FFをN個連結して、クロックをK回入れたらどうなりますかっていう話なので、英語さえ読めればコードは楽勝。
#include <cstdio> using namespace std; int main() { int T; scanf("%d", &T); for (int t = 0; t < T; ++t) { printf("Case #%d: ", t+1); int N, K; scanf("%d%d", &N, &K); if (K % (1 << N) == (1 << N) - 1) puts("ON"); else puts("OFF"); } }
B. Fair Warning
一番悩んだ。
条件式を変形していくと
ti + y = 0 (mod T)
ti = -y (mod T)
t1 = t2 = ... = tn = -y (mod T)
t1 = t2 かつ t2 = t3 かつ ... かつ tn-1 = tn (mod T)
t1 - t2 = 0 かつ t2 - t3 = 0 かつ ... かつ tn-1 - tn = 0 (mod T)
となる。最後の式は、Tが{ti - ti+1}の公約数であることを意味する。
逆に、Tが{ti - ti+1}の公約数であれば、条件を満たすyが存在する。(例えば y = (T - (t1 % T)) % T があり、実はこれが最小のy)
よってTの最大値は{ti - ti+1}の最大公約数。
require 'mathn' gets.to_i.times do |c| n, *ts = gets.split.map{|s| s.to_i} g = (ts[1] - ts[0]).abs for i in (1..n-2) g = g.gcd((ts[i+1] - ts[i]).abs) end puts "Case ##{c + 1}: #{(g - ts[0] % g) % g}" end
C. Theme Park
周期性を利用する。
もし、ある2つの時点で、コースターに乗る先頭のグループが同じなら、それ以降は全く同じ状況が起こる。先頭の選び方はN通りしかないので、高々N+1回でコースターに乗る先頭のグループが同じという状況が起こる。その後は、ループが1週したときの儲け * ループする回数 で一気に計算できる(余りの部分は適当になんとかする)。
#include <cstdio> #include <cstring> #include <cassert> using namespace std; long long g[1000]; int turn[1000]; long long money[1000]; int main() { int T; scanf("%d", &T); for (int t = 0; t < T; ++t) { memset(turn, -1, sizeof(turn)); memset(money, -1, sizeof(money)); int R, k, N; scanf("%d%d%d", &R, &k, &N); for (int i = 0; i < N; ++i) { scanf("%lld", g+i); } int head = 0; long long m = 0; for (int i = 0; i < R; ) { if (turn[head] != -1) { long long period = i - turn[head]; long long mouke = m - money[head]; long long times = (R - i) / period; assert(mouke * times >= 0); assert(period * times >= 0); m += mouke * times; i += period * times; memset(turn, -1, sizeof(turn)); memset(money, -1, sizeof(money)); } else { money[head] = m; turn[head] = i; long long n_ride = 0, j; for (j = head; ; j = (j + 1) % N) { if (j == head && n_ride > 0) break; if (n_ride + g[j] > k) break; n_ride += g[j]; } m += n_ride; head = j; ++i; } assert(m >= 0); } printf("Case #%d: %lld\n", t+1, m); } }