wannafly挑战赛24 A 石子游戏 (博弈论)

大致题意

Alice和Bob在玩游戏,他们面前有n堆石子,对于这些石子他们可以轮流进行一些操作,不能进行下去的人则输掉这局游戏。
可以进行两种操作:

  1. 把石子数为奇数的一堆石子分为两堆正整数个石子
  2. 把两堆石子数为偶数的石子合并为一堆
    两人都足够聪明,会按照最优策略操作。现在Alice想知道自己先手,谁能最后赢得比赛。
输入

第一行一个正整数n。(1<=n<=1e4)
接下来第二行n个正整数表示每堆石子的数量。每堆石子不超过1e5个。

输出

Alice或者Bob,表示谁能最后赢得游戏。

思路

对于一个偶数的石子,若有 x 个,每次合并减少一个石子,最多操作 x-1 次,现在来看奇数的石子,奇数可以拆成一个奇数一个偶数,带来的结果是,多操作了一次,偶数石子要多合并一次,所以等于没有变化。当然除了 1 ,1 不能分。 所以最终是求偶数石子的个数即可。

代码

#include
using namespace std;
#define maxn 10005
#define maxm 1006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (1ll*x*x)
#define inf (ll)2e18+1
#define PI acos(-1)
#define mod 10007
#define auto(i,x) for(int i=head[x];i;i=ed[i].nxt)
#define mkp make_pair
ll read(){
    ll x=0,f=1ll;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
     return f*x;
}
int n,x;
int main()
{
    n=read();
    int flag=0,win=0;
    inc(i,1,n){
        x=read();
        if(x==1)continue;
        flag=1;
        if((x&1)==0)win^=1;///==的运算优先级太高记得加括号
    }
    if(!flag||win)printf("Bob\n");
    else printf("Alice\n");
    return 0;
}

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