题目:
Alice and Bob are playing game of Misère Nim. Misère Nim is a game playing on k piles of stones, each pile containing one or more stones. The players alternate turns and in each turn a player can select one of the piles and can remove as many stones from that pile unless the pile is empty. In each turn a player must remove at least one stone from any pile. Alice starts first. The player who removes the last stone loses the game.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case starts with a line containing an integer k (1 ≤ k ≤ 100). The next line contains k space separated integers denoting the number of stones in each pile. The number of stones in a pile lies in the range [1, 109].
Output
For each case, print the case number and 'Alice' if Alice wins otherwise print 'Bob'.
Sample Input
3
4
2 3 4 5
5
1 1 2 4 10
1
1
Sample Output
Case 1: Bob
Case 2: Alice
Case 3: Bob
题意:
T组测试数据,K代表有K堆石子,然后有K个数字代表每堆石子的石子个数;
Alice先手,Bob后手,每个人可以在任意一堆石子中拿走任意个石子,但是不能不拿,最后拿石子的人认为输了游戏,让你求出是谁赢得了比赛。
思路:
这是一道博弈题,符合Nim博弈的条件:
1、有两名选手;
2、两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动;
3、对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作、以前的任何操作、骰子的点数或者其它什么因素;
4、如果轮到某名选手移动,且这个局面的合法的移动集合为空(也就是说此时无法进行移动),则这名选手负。根据这个定义,很多日常的游戏并非ICG。例如象棋就不满足条件3,因为红方只能移动红子,黑方只能移动黑子,合法的移动集合取决于轮到哪名选手操作。
Nim定义:
有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。
逆Nim:
有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判赢,即最后一个取石子的人输。
首先我们要理解P-position和N-position的含义:
P-position:P--previous,先行者输,后行者赢;
N-position:N--next,后行者输,先行者赢;
Terminal position--无法移动的局面;
所有可以移动到P-position局面的情况都是N-position 局面;
所有可以移动到N-position局面的情况都是P-position局面;
当然了,Terminal position 都是P-position局面,因为先手没有任何合法的移动,所以先手赢;
判断:
1.对于Terminal position只有一个,也就是全为0,结果也为0,故先行者必输。
2.某个局面(a1,a2,...,an),若a1^a2^......^an=k(k不等于0),则必有一种局面ai能够通过合法的步骤转换为ai',使结果变为0(k二进制中的某一位中的1必定是某个ai贡献过来的),其中ai^k=ai'<ai(ai在k的二进制下最高位是1),所以是后行者必输。
3.某个局面(a1,a2,...,an),若a1^a2^......^an=0,若ai能够通过合法的步骤转换成另一个局面ai'使结果也为0,那么a1^a2^..^ai^...^an=a1^a2^..^ai'^...^an,根据消去律,得到ai=ai',这是不合法的移动(因为还是它本身),所以是先行者必输。
我们可以使用异或,利用它的消去律来计算;
代码如下:
#include<stdio.h>
#include<string.h>
int t,k,ans;
long long a;
int main()
{
int kk=1;
scanf("%d",&t);
while(t--)
{
ans=0;
int sum=0;
scanf("%d",&k);
for(int i=0; i<k; i++)
{
scanf("%lld",&a);
if(a>=2)
sum++;
ans=ans^a;
}
if((ans==0&&sum==0)||(ans!=0&&sum!=0))
printf("Case %d: Alice\n",kk++);
else
printf("Case %d: Bob\n",kk++);
}
return 0;
}