cafelier のSRM参加記録です。コンテスト中に考えてたことを執拗に全部書き残すとどうなるだろうかという試み本番中にこういうコードが書きたかったなあ、という後で書いた反省コードを書き残す試み
スパムが来たのでしばらくコメント欄をはてなユーザ限定にしています、すみません、
あとで | |
不参加。Practice でやってみたら (×, 300点くらい, 480点くらい) でした。参加者さんのスコアだけは見てたので500は十分解ける問題とわかっていたので解けたけど、本番だと500は多分テンパって解けてない気がする。
class ChickenOracle { public: string theTruth(int n, int eggCount, int lieCount, int liarCount) { bool egg = canTruthTellerBe( eggCount, n, lieCount, liarCount ); bool chk = canTruthTellerBe( n-eggCount, n, lieCount, liarCount ); if( egg && chk ) return "Ambiguous"; if( egg ) return "The egg"; if( chk ) return "The chicken"; return "The oracle is a lie"; } bool canTruthTellerBe( int A, int n, int B, int C ) { int two_x = A+B+C - n; if( (two_x&1) == 1 ) return false; int x = two_x/2; return 0<=x && x<=C && x<=B && (C-x)<=(n-B); } };
class BatchSystemRoulette { public: vector <double> expectedFinishTimes(vector <int> duration, vector <string> user) { vector<double> answer(duration.begin(), duration.end()); map<string, LL> userSum; for(int i=0; i<user.size(); ++i) userSum[user[i]] += duration[i]; map<LL, vector<string> > usInv; for(map<string,LL>::iterator it=userSum.begin(); it!=userSum.end(); ++it) usInv[it->second].push_back(it->first); double base = 0; for(map<LL, vector<string> >::iterator it=usInv.begin(); it!=usInv.end(); ++it) { LL t = it->first; vector<string>& us = it->second; int n = us.size(); double baseAve = base + t*(n-1)/2.0; for(int u=0; u<n; ++u) { vector<int> idxs; for(int i=0; i<answer.size(); ++i) if( user[i] == us[u] ) { answer[i] += baseAve; idxs.push_back(i); } for(int k=0; k<idxs.size(); ++k) { int i = idxs[k]; for(int m=0; m<idxs.size(); ++m) if(m!=k) { int j = idxs[m]; answer[i] += duration[j]/2.0; } } } base += t*n; } return answer; } };
template<typename T> struct DP3 { int N1, N2, N3; vector<T> data; DP3(int N1, int N2, int N3, const T& t = T()) : N1(N1), N2(N2), N3(N3), data(N1*N2*N3, t) { assert(data.size()*sizeof(T)<(1<<26)); } T& operator()(int i1, int i2, int i3) { return data[ ((i1*N2)+i2)*N3+i3 ]; } void swap(DP3& rhs) { data.swap(rhs.data); } }; int bitcnt(int U) { int c = 0; for(; U; U>>=1) c += (U&1); return c; } class TicketPrinters { public: int minTime(int currentPrinter, vector <int> printerDistance, vector <int> startingValues, vector <int> wantedValues) { int N = startingValues.size(); vector<int> d(N); partial_sum( printerDistance.begin(), printerDistance.end(), d.begin()+1 ); // left, used, LeftOrRight DP3<int> dp(N,1<<N,2); for(int D=(1<<N)-1; D>=0; --D) { int bc = bitcnt(D); for(int L=0; L<N && L+bc<=N; ++L) for(int C=0; C<=1; ++C) { if( bc == N ) dp(L,D,C) = 0; else { int cur = (C==0 ? L : L+bc-1); int mn = 0x7fffffff; for(int nextW=0; nextW<N; ++nextW) if( ((1<<nextW) & D) == 0 ) { int caseLeft = 0x7fffffff; if( L>0 ) { caseLeft = d[cur] - d[L-1] + max(dp(L-1, D|1<<nextW, 0), 1+abs(startingValues[L-1]-wantedValues[nextW])); } int caseRight = 0x7fffffff; if( L+bc < N ) { caseRight = d[L+bc] - d[cur] + max(dp(L, D|1<<nextW, 1), 1+abs(startingValues[L+bc]-wantedValues[nextW])); } mn = min(mn, min(caseLeft, caseRight)); } dp(L,D,C) = mn; } } } return dp(currentPrinter,0,0); } };
presented by cafelier/k.inaba under