题目概述
给出一个
Nim
游戏:
n
堆石子,每堆石子
解题报告
太菜了……刚学 Nim 游戏……
Nim
游戏的简化模型就是
n
堆石子,每堆石子
那么
Nim
游戏就有必胜态
W
和 必败态
- 无法操作的状态是 L 。
- 有一个子状态是
L 的状态是 W 。 - 没有一个子状态是
L 的状态是 L 。
那么怎么判断一个状态是
可怕的地方来了……有一个定理:如果
ai
的异或和
Xor=0
,那么就是
L
,否则就是
- 当无法操作时, Xor 显然为 0 。
- 当状态是
W 时, Xor>0 ,我们一定可以找到一个 ai ,满足 ai 在 Xor 的最高位上的数为 1 (二进制),这样ai xor Xor<ai 且 (Xor xor ai) xor (ai xor Xor)=0 ,说明有一个子状态为 L 。 - 当状态是
L 时, Xor=0 ,则不可能找到2中的 ai ,所以没有一个子状态为 L 。
然而这道题更鬼畜一点,怎么求对手必败的方案数?我们来想,如果
示例程序
#include<cstdio>
using namespace std;
const int maxn=1000;
int n,a[maxn+5],nim,ans;
int main()
{
freopen("program.in","r",stdin);
freopen("program.out","w",stdout);
for (scanf("%d",&n);n;scanf("%d",&n))
{
nim=0;for (int i=1;i<=n;i++) scanf("%d",&a[i]),nim^=a[i];
ans=0;for (int i=1;i<=n;i++) ans+=(nim^a[i])<a[i];printf("%d\n",ans);
}
return 0;
}