题目链接
链接:https://www.nowcoder.com/acm/contest/186/A
来源:牛客网
Alice和Bob在玩游戏,他们面前有n堆石子,对于这些石子他们可以轮流进行一些操作,不能进行下去的人则输掉这局游戏。
可以进行两种操作:
1. 把石子数为奇数的一堆石子分为两堆正整数个石子
2. 把两堆石子数为偶数的石子合并为一堆
两人都足够聪明,会按照最优策略操作。现在Alice想知道自己先手,谁能最后赢得比赛。
输入描述:
第一行一个正整数n。(1<=n<=104)
接下来第二行n个正整数表示每堆石子的数量。每堆石子不超过105个。
输出描述:
Alice或者Bob,表示谁能最后赢得游戏。
示例1
输入
复制
3
3 2 2
输出
复制
Alice
说明
Alice只要现将两个石子数量为2的堆合并为一堆4个石子,Bob就只能把3分为两堆1和2,接下来Alice只要将2和4合并,Bob输掉了这局游戏。
题解
很明显问题的核心在大于1的奇数的处理上,我们先从特殊的考虑,3只能分成1和2,然后2可以和另外的偶数合并一次,5可以分成1和4(次数为2) 或 2和3(次数为4),然后我们可以发现奇数的分解带来的次数增加都是偶数次的(这里有一个前提就是已存在偶数,处理这里的方法就是最后统计的时候减1)
然后就是特殊情况的考虑,假如全是1,那么先手必败
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
//head
int n;
int a[20005];
int main(int argc, char const *argv[])
{
cin>>n;
int t = 0;
int t2 = 0;
rep(i,0,n)
{
cin>>a[i];
if(a[i] % 2 && a[i] != 1)
t++;
if(a[i] % 2 == 0)
t2++;
}
t = t * 2 + (t2-1);
if(t < 0)//全是1
t = 0;
if(t % 2)
cout<<"Alice"<<endl;
else
cout<<"Bob"<<endl;
return 0;
}