Nim or not Nim? HDU - 3032 博弈论&&nim游戏&&sg函数打表

Nim is a two-player mathematic game of strategy in which players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap. 

Nim is usually played as a misere game, in which the player to take the last object loses. Nim can also be played as a normal play game, which means that the person who makes the last move (i.e., who takes the last object) wins. This is called normal play because most games follow this convention, even though Nim usually does not. 

Alice and Bob is tired of playing Nim under the standard rule, so they make a difference by also allowing the player to separate one of the heaps into two smaller ones. That is, each turn the player may either remove any number of objects from a heap or separate a heap into two smaller ones, and the one who takes the last object wins.

Input

Input contains multiple test cases. The first line is an integer 1 ≤ T ≤ 100, the number of test cases. Each case begins with an integer N, indicating the number of the heaps, the next line contains N integers s[0], s[1], ...., s[N-1], representing heaps with s[0], s[1], ..., s[N-1] objects respectively.(1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)

Output

For each test case, output a line which contains either "Alice" or "Bob", which is the winner of this game. Alice will play first. You may asume they never make mistakes.

Sample Input

2
3
2 2 3
2
3 3

Sample Output

Alice
Bob

题意:有n堆石子 每次可以取任意个或者把一堆石子分为两堆不为零的石子

题解:对于分成两堆来说,相当于又分成了两个子游戏

子游戏的和是所有子游戏sg值异或的结果

比如x=3,子状态有 0,1,2,(1,2) 然后(1,2)相当于sg[1]^sg[2] ,最后的集合就是sg[3]=mex{sg[0],sg[1],sg[2],sg[sg[1]^sg[2]]}

再求一下最大非负整数就行了

通过打表可以发现一个很明显的结论

  • if(x%4==0) sg[x]=x-1;
  • if(x%4==1||x%4==2) sg[x]=x;
  • if(x%4==3) sg[x] = x+1。                                                 
    #include
    #include
    #include
    using namespace std;
    #define N 1000000
    
    int T,n,x,ans;
    
    int get_sg(int x)
    {
        if (x%4==0) return x-1;
        else if (x%4==1||x%4==2) return x;
        else if (x%4==3) return x+1;
    }
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);ans=0;
            for (int i=1;i<=n;++i)
            {
                scanf("%d",&x);
                ans^=get_sg(x);
            }
            if (ans) printf("Alice\n");
            else printf("Bob\n");
        }
    }

     

你可能感兴趣的:(博弈论)