Google Code Jam 2013 Round1A
旅行中だったので、11:00-12:30を電車移動にあてて頑張ってみました。
- -
A : Bullseye
- 電車に乗ってから30分くらい席が空かなかったのでnexusで問題文だけ見てた。
- オーバーフローに気をつけて2分探索すれば良かろう…という印象を受ける。
- 脳内で組んだ式が間違ってたり誤読してたりして、不覚にも実装で詰まった。
#include <iostream> #include <cstdio> using namespace std; long long valid(long long p, long long c, long long n){ return n*(2*(p+n)-1) <= c; } int main(){ int T; cin >> T; long long p, c; for(int test=1;test<=T;test++){ cin >> p >> c; long long L = 1, R = 2; while(valid(p, c, R)) L *= 2, R *= 2; while(R-L>1){ long long mid = (L+R)/2; if(valid(p, c, mid)) L = mid; else R = mid; } printf("Case #%d: %lld\n", test, L); } }
B : Manage your Energy
- 問題文を読み、smallはDPでどうにでもなりそうという感想を持つ。
- largeは貪欲にアレをアレしたら良さそう、というふわふわした感じ。
- んで、standingsを見てlarge特攻しかない!という気持ちになってしまった。
- 電車内で書いたのはバグって通らなかった。
- 方針は、「イベント開始時に残せる最大エネルギー」と「開始後に最低でも残さないといけないエネルギーを持っておくというもの。
- 報酬がでかいイベントから順に、最大エネルギーと最低エネルギーの差を使い、O(n)かけて前後のイベントの値を変更していけば良いと思った。
- 全体でO(n^2)。下のコードは後日デバッグしたもの。
#include <iostream> #include <vector> #include <cstdio> #include <algorithm> using namespace std; long long solveLarge(){ static int lower[10000], upper[10000], used[10000]; int E, R, N; cin >> E >> R >> N; for(int i=0;i<N;i++){ lower[i] = 0; upper[i] = E; used[i] = 0; } vector< pair<int, int> > vp; for(int i=0;i<N;i++){ int t; cin >> t; vp.push_back(make_pair(-t, i)); } sort(vp.begin(), vp.end()); long long res = 0; for(int i=0;i<N;i++){ int idx = vp[i].second; long long t = -vp[i].first; res += (upper[idx]-lower[idx])*t; used[idx] = 1; for(int j=1; ;j++){ if(idx-j < 0) break; if(used[idx-j]) break; lower[idx-j] = max((long long)lower[idx-j], upper[idx]-j*(long long)R); } for(int j=1; ;j++){ if(idx+j >= N) break; if(used[idx+j]) break; upper[idx+j] = min((long long)upper[idx+j], lower[idx]+j*(long long)R); } } return res; } int main(){ int T; cin >> T; for(int test=1;test<=T;test++){ printf("Case #%d: %lld\n", test, solveLarge()); } }
C : Good Luck
- 問題読んで(+standings眺めて)Largeやばそう(小並感)と思った。
- Smallはやりゃ通るだろ(傲慢)という感じでしたが、Bで詰まったのでやれず。
- コードは当時脳内で予定してたのを書いてみたもの。Smallは通った。
#include <iostream> #include <string> #include <cstdio> using namespace std; string solveSmall(int N, int M, int K){ int m2 = 0, m3 = 0, m5 = 0; for(int i=0;i<K;i++){ int v; cin >> v; int t2 = 0, t3 = 0, t5 = 0; while(v%2==0) v /= 2, t2++; while(v%3==0) v /= 3, t3++; while(v%5==0) v /= 5, t5++; m2 = max(m2, t2); m3 = max(m3, t3); m5 = max(m5, t5); } if(m2==6) return "444"; if(m2==5) return "442"; if(m2==4){ if(m3+m5==0) return "224"; if(m3) return "344"; if(m5) return "445"; } if(m2==3){ if(m3+m5==0) return "222"; if(m3) return "234"; if(m5) return "245"; } if(m2==2){ if(m3+m5<=1){ if(m3) return "223"; else return "225"; } else { string res = "4"; for(int i=0;i<m3;i++) res += "3"; for(int i=0;i<m5;i++) res += "5"; return res; } } string res = ""; for(int i=0;i<m2;i++) res += "2"; for(int i=0;i<m3;i++) res += "3"; for(int i=0;i<m5;i++) res += "5"; while(res.size() < N) res += "2"; return res; } int main(){ int T; cin >> T; for(int test=1;test<=T;test++){ int R, N, M, K; cin >> R >> N >> M >> K; printf("Case #%d:\n", test); for(int i=0;i<R;i++) cout << solveSmall(N, M, K) << endl; } }
- -
Rank 2144 : /oo/x-/--/ Score 24, Penalty 1:58:39
Round1Bから本気だす(予定)