[ SDOI 2016 ] 硬币游戏

题目

Luogu
LOJ
Acwing

思路

001.png

代码

#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;
}
posted @ 2021-07-14 19:27  Protein_lzl  阅读(86)  评论(0编辑  收藏  举报