可以参考Thomas S. Ferguson的《Game Theory》,网上的博客大多也是根据这个翻译过来的,第五章讲了很多关于翻硬币的博弈。
这种博弈属于Mock Turtles,它的SG函数值是2x或2x+1.
把一个数写成二进制的形式,如果1的个数为奇数,把这种数叫做odious;否则就叫做evil。 话说这种名字好奇怪啊,= ̄ω ̄=
所以把每个正面朝上的硬币对应SG函数值异或起来就能得到答案。
还有这个题的坑就是:输入的数中可能有重复,所以去重后再计算!

1 #include <cstdio> 2 #include <set> 3 using namespace std; 4 5 int SG(int x) 6 { 7 int c = 0, t = (x << 1); 8 while(x) 9 { 10 if(x & 1) c++; 11 x >>= 1; 12 } 13 return (c & 1) ? t : t + 1; 14 } 15 16 int main() 17 { 18 int n; 19 while(scanf("%d", &n) == 1) 20 { 21 set<int> hehe; 22 int a, sum = 0; 23 for(int i = 0; i < n; i++) 24 { 25 scanf("%d", &a); 26 if(hehe.count(a)) continue; 27 hehe.insert(a); 28 sum ^= SG(a); 29 } 30 printf("%s ", sum ? "No" : "Yes"); 31 } 32 33 return 0; 34 }