Alice and Bob

类似于石子合并的游戏,在黑板上写下N个数,每次只能将其中的一个数减1(结果为0自动消去),或者将某两个数消去,将其和写在黑板上。

Alice先手,彼此都采用最优策略,将最后一个数消去者获胜。

思路:设s为石子总数,n为总堆数,分3种情况:

(1).全1 :如果n能被3整除,先手败,否则先手胜。

(2).有一个2,其余为1:如果n除以3余数为1,先手败,否则先手胜。

(3)其他情况:

        a)1的个数为奇数,先手胜。

        b)1的个数为偶数,且s+n-1为奇数,先手胜。

        c)1的个数为偶数,且s+n-1为偶数,先手败。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 50+5;
int a[MAXN];
 
int main()
{
    int t,n,num1,num2;
    long long sum;
    scanf("%d",&t);
    for(int cnt = 1; cnt <= t; cnt++)
    {
        scanf("%d",&n);
        sum = 0; num1 = 0; num2 = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d",&a[i]);
            if(a[i] == 1) num1++;
            else if(a[i] == 2) num2++;
            sum += a[i];
        }
        if(num1 == n)
        {
            if(n%3 == 0) printf("Case #%d: Bob
",cnt);
            else printf("Case #%d: Alice
",cnt);
        }
        else if(num2 == 1 &&num1 + num2 == n)
        {
            if(n%3 == 1) printf("Case #%d: Bob
",cnt);
            else printf("Case #%d: Alice
",cnt);
        }
        else
        {
            if(num1%2 == 1) printf("Case #%d: Alice
",cnt);
            else
            {
                if((sum + n -1)%2 == 1) printf("Case #%d: Alice
",cnt);
                else printf("Case #%d: Bob
",cnt);                    
            }
        }
    }
    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/chenbjin/p/3279183.html