[ SDOI 2016 ] 硬幣遊戲
阿新 • • 發佈:2021-07-14
題目
思路
程式碼
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 30010; int T, n, MAXQ, SG[20][20]; int get(int x, int k) { int t = 0; while (x % k == 0) x /= k, t++; return t; } int cnt[500]; void pre() { memset(SG, 0, sizeof SG); int a = n, b = n, x = 0, y = 0; while (a >= 2) x++, a /= 2; while (b >= 3) y++, b /= 3; for (int i = 0; i <= x; i++) { for (int j = 0; j <= y; j++) { memset(cnt, 0, sizeof cnt); for (int p = 1; p <= i; p++) for (int q = 1; q <= MAXQ && p * q <= i; q++) { int t = -1; for (int k = 1; k <= q; k++) t = (t == -1) ? SG[i - p * k][j] : (t ^ SG[i - p * k][j]); if (t != -1) cnt[t] = 1; } for (int p = 1; p <= j; p++) for (int q = 1; q <= MAXQ && p * q <= j; q++) { int t = -1; for (int k = 1; k <= q; k++) t = (t == -1) ? SG[i][j - p * k] : (t ^ SG[i][j - p * k]); if (t != -1) cnt[t] = 1; } for (int t = 0; ; t++) if (!cnt[t]) { SG[i][j] = t; break; } } } } int main() { cin >> T; while (T-- && cin >> n >> MAXQ) { pre(); int res = 0; for (int i = 1, t; i <= n && cin >> t; i++) if (t == 0) res ^= SG[get(i, 2)][get(i, 3)]; cout << (res ? "win" : "lose") << endl; } return 0; }