这个游戏是说,有m堆硬币,两个人分别来取,每人每次能从任意一堆中去任意多的硬币(但只能从一堆中取),现在告诉你具体每堆的数量,然后让你判断先取者胜,还是后取者胜。
解:
设每堆的数量为:a1, a2, a3,.....am;
由于每一个整数都能表示成二进制数,那么将这些数表示成二进制:
a1 = b(m-1)b(m-2)b(m-3)....b0;
a2 = c(m-1)c(m-2)c(m-3)....c0;
..........(位数不够的用零补齐)
现在设 :
若 b(m-1) + c(m-1) + ...... == 偶数, 则称第 j 位是平衡的,否则是不平衡的。若在某状态下,所有位都是平衡的,则该状态为平衡状态,否则为非平衡状态。
现在,该问题的一个解释:初始状态为平衡状态时,后取者胜,否则先取者胜。
原因:
当初始状态状态为非平衡状态时,假设最大非平衡状态位为第 j 位,那么先取者一定能从第 j 位是1的某一堆中去一定数量的硬币使状态变为平衡状态。现在后取者无论怎么取都得给先取者留下不平衡的状态......然后先取者再将其变平衡即可,这样往复循环 先取者最终将状态变为 所有都为零的平衡状态。
当初始状态为平衡状态,调换顺序即可。
该游戏在HDOJ上有一题http://acm.hdu.edu.cn/showproblem.php?pid=2176
代码如下:
#include <iostream>
using namespace std;
int main(){
int a[200000], n, t;
while( cin >> n, n ){
t = 0;
for( int i = 0; i < n; i++ ){
cin >> a[i];
t ^= a[i];
}
if( t == 0 ){
cout << "No" << endl;
}else{
cout << "Yes" << endl;
for( int i = 0; i < n; i++ ){
if( ( t ^ a[i] ) < a[i] ){
cout << a[i] << " " << ( t ^ a[i] ) << endl;
}
}
}
}
}