在有向无环图上,有多个棋子,双方轮流操作,每次选择一枚棋子移动,谁无法移动谁就输了。
对于每个点计算SG值,SG值为所有能走到的点的mex。
mex(S)表示S集合中没出现过的最小的自然数。
这类题目往往需要通过暴力求出SG值,之后再找规律
将取石子游戏的谁取最后一个赢,改为谁取最后一个输。
检查是否有一堆石子个数大于1,
如果有,和之前的版本一样,异或为0,先手必败,异或非0,先手必胜。
如果没有,和之前的版本相反,异或为0,先手必胜,异或非0,先手必败。
https://en.wikipedia.org/wiki/Nim
堆石子,第堆石子有个,两个玩家轮流取走任意一堆的任意个物品,不能不取,无法操作的输。
这是一个经典问题,如果所有的异或是,那么先手必败,否则先手必胜。
可以简单的理解为,必胜策略就是保证自己操作之后,所有的异或为,对手的操作必然破坏这性质,自己需要再进行一次操作使得所有异或为零。
所有石子个数 xor
如果结果非0,先手必胜
如果结果是0,先手必败game
hdu 3590
这是一个错题。
1
5
1 2
2 4
1 3
3 5
上面这个个点的数据,先手必败,但是标程会输出先手必胜。
SG值为0也可以操作
hdu 3197
hdu 3094
砍树游戏,每个点的SG值等于所有孩子节点的SG值加一的异或。
http://poj.org/problem?id=2311
局面会拆分的SG
https://acm.hdu.edu.cn/showproblem.php?pid=2873
局面会拆分的SG
https://www.luogu.com.cn/problem/P4702
Alice 和 Bob 在玩游戏。
他们有 堆石子,第 堆石子有 个,保证初始时 。现在他们轮流对这些石子进行操作,每次操作人可以选择满足 ( 视为 )的一堆石子,并从中取走一个。谁最后不能取了谁输。Alice 先手,他们都使用最优策略,请判断最后谁会取得胜利。
第一行一个整数 ,表示石子堆数。
接下来一行 个数,第 个数为 ,意义如上所述。
"Alice" 或 "Bob",表示谁会赢。
1
1
Alice
1
2
Bob
#include <bits/stdc++.h> using namespace std; int n, x; long long s; int main() { cin >> n; for (int i = 0; i < n; i++) { cin >> x; s += x; } cout << (s & 1 ? "Alice" : "Bob") << endl; return 0; }