SnackDown Online Qualifier 2016 - Floor Division Game
解法
grundy 数に規則性がある (のを uwi さんに教えてもらった) ので、それを先に作っておいて、参照しながら求めると良い。
コード
#include <bits/stdc++.h> using namespace std; int main() { cin.tie(0); ios::sync_with_stdio(false); // 先に grundy 数の map を作っておく map<int64_t, int> nim; nim[0] = 0; nim[1] = 1; nim[2] = 2; nim[4] = 3; int p = 3; while (nim.rbegin()->first < 1e18) { int64_t n = nim.rbegin()->first; if (nim.size() % 4 == 0) { n += n / 2; } else { n *= 2; } nim[n] = (++p) % 4; } int T; cin >> T; while (T--) { int N; cin >> N; vector<int64_t> A(N); for (int i = 0; i < N; ++i) { cin >> A[i]; } vector<int> G(N); for (int i = 0; i < N; ++i) { auto it = nim.upper_bound(A[i]); it--; G[i] = it->second; } int grundy = 0; for (int i = 0; i < N; ++i) grundy = grundy ^ G[i]; if (grundy > 0) cout << "Henry" << endl; else cout << "Derek" << endl; } }