ZOJ3067_Nim

题目的意思就不说了,典型的取石子的博弈问题。

题目的前半部分就是赤果果的SG函数值异或就可以了,其中Sg函数值就是石子数本身。

但是接下来有个小变换,就是要你输出先手必胜有多少种不同的取法。

首先要想保持必胜,必须要取完以后保证所有的石子数异或值为0.

这样,假设我们来判断某一堆是否可取的时候,我们可以用总的异或值来与当前堆石子数异或一下,就得出当前堆应该剩下多少石子哦(仔细理解这里就好了)

下面可以贴代码了:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 int a[1005],n,m,ans;
 6 
 7 int main()
 8 {
 9     while (scanf("%d",&n) && n)
10     {
11         ans=m=0;
12         for (int i=1; i<=n; i++) scanf("%d",&a[i]),m^=a[i];
13         if (m==0)
14         {
15             printf("0
");
16             continue;
17         }
18         for (int i=1; i<=n; i++)
19             if ((a[i]^m)<a[i]) ans++;//一开始的时候我的判断条件是<=,居然也对了,诶数据略水,这里必须是严格的小于。
20         printf("%d
",ans);
21     }
22     return 0;
23 }
如有转载,请注明出处(http://www.cnblogs.com/lochan)
原文地址:https://www.cnblogs.com/lochan/p/3375083.html