您的位置:首页 > 其它

[BeiJing2009 WinterCamp] bzoj1874 取石子游戏 [博弈论]

2018-03-12 11:16 309 查看
Description:

小H和小Z正在玩一个取石子游戏。 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,

每次取石子的个数有限制,谁不能取石子时就会输掉游戏。 小H先进行操作,他想问你他是否有必胜策略,如果有

,第一步如何取石子。

Solution:

暴力求出sgsg函数,判断每个子游戏也就是石子堆的异或和是否为00,为00则输出NONO,否则枚举选哪堆石子,拿多少,判断sgsg函数是否为00即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int n, m;
int a
, b
, vis
, sg
;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
scanf("%d", &m);
for(int i = 1; i <= m; ++i) {
scanf("%d", &b[i]);
}
for(int i = 1; i <= 1000; ++i) {
memset(vis, 0, sizeof(vis));
for(int j = 1; j <= m; ++j) {
if(i >= b[j]) {
vis[sg[i - b[j]]] = 1;
}
}
for(int j = 0; j <= 1000; ++j) {
if(!vis[j]) {
sg[i] = j;
break;
}
}
}
int ans = 0;
for(int i = 1; i <= n; ++i) {
ans ^= sg[a[i]];
}
if(!ans) {
puts("NO");
} else {
puts("YES");
int ans1 = 0, ans2 = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if(a[i] >= b[j] && (ans ^ sg[a[i]] ^ sg[a[i] - b[j]]) == 0) {
printf("%d %d\n", i, b[j]);
return 0;
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: