K - Misere Nim

题目:

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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值