hdu 3032(博弈)

4 篇文章 0 订阅

题意:
有两种操作可选:1.从一堆中拿任意多个(不为0)2.将其中任意一堆分为两堆。不能再操作者输。
sg[0] = 0;
sg[1] = 1;
n = 2, 可分为0, 1, (1, 1)sg[2] = 2;
以此类推,打表观察得 n % 4 == 1 || n % 4 == 2, sg[n] = n;
n % 4 == 0, sg[n] = n - 1;
n % 4 == 3, sg[n] = n + 1;

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define LL long long
#define MAX 0x3f3f3f3f
#define N (1000000 + 5)

using namespace std;

int sg[N], hash[N];

// void init()
// {
//  memset(sg, 0, sizeof(sg));

//  sg[0] = 0;
//  sg[1] = 1;
//  sg[2] = 2;
//  sg[3] = 4;  

//  for (int i = 4; i < N; i++)
//  {
//      memset(hash, 0, sizeof(hash));
//      for (int j = 0; j < i; j++)
//      {
//          hash[sg[j]] = 1;
//      }
//      for (int j = 1; j <= i / 2; j++)
//      {
//          int tmp = sg[j] ^ sg[i - j];
//          hash[tmp] = 1;
//      }
//      for (int j = 0; j < N; j++)
//      {
//          if (hash[j] == 0)
//          {
//              sg[i] = j;
//              break;
//          }
//      }
//  }

//  for (int i = 0; i <= 50; i++)
//  {
//      cout << i << ' ' << sg[i] << endl;
//  }
// }

int main()
{
    int T;
    scanf("%d", &T);

    // init();

    while (T--)
    {
        int n;
        scanf("%d", &n);

        int t, ans = 0;

        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &t);
            if (t % 4 == 0)
            {
                ans = (ans ^ (t - 1));
            }
            else if (t % 4 == 3)
            {
                ans = (ans ^ (t + 1));
            }
            else
            {
                ans = (ans ^ t);
            }
        }

        if (ans != 0)
        {
            cout << "Alice" << endl;
        }
        else
        {
            cout << "Bob" << endl;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值