SP9934 ALICE - Alice and Bob【题解】
- 2021.7.30 增加公式与文字之间忘加的空格以及公式错用。
博弈论
复杂度:
此外,也是码量最小的解法。
我们设
当拿走只有
假设
- 假设
most 是奇数且most\ge3 - 则先手的目的就是保证操作最多即可(显然操作数是奇数时,先手必胜),所以先手不会拿走
1 (单独一堆)来改变先后手,先手会尽可能合并两个1 (单独一堆)来保证对手不能改变先后手,若后手拿走一张1 (单独一堆),先手也必须拿走一堆保证先后手不变。所以不难看出,先手要想赢的话,每轮操作都会减少两个1 的数量(合并两个1 ;后手拿一个,先手拿一个)。-
- 为了不让后手拿到被动优势,先手可以将 $1$ (单独一堆)合并到其他不为 $1$ 的堆里去,这时场上的 $1$ 一定是偶数,然而后手必须要改变先后,但是那样他又没有被动优势,要是为了拿到被动优势,又拿不到先后,所以先手必胜。 -
- 这时先手合并两个 $1$ 即可得到被动优势,后手又像上面说的不能两全其美(改变先后和拿到被动优势),先手必胜。
-
- 则先手的目的就是保证操作最多即可(显然操作数是奇数时,先手必胜),所以先手不会拿走
- 假设
most 是偶数且most\ge2 - 此时先手一定要改变先后(拿走单个)。
-
- 此时先手可以直接拿走一张(改变先后),为了挽回,后手只能拿一张(否则相当于投降),拿几轮后最后一定只剩一堆单个的了,控制权此时在先手,先手必赢。 -
- 此时先手不能两全其美,先手必输。
-
- 此时先手一定要改变先后(拿走单个)。
综上所述
但是当
-
0$ 个 $1 - 显然,先手必输。
-
1$ 个 $1 - 显然,先手必赢。
-
2$ 个 $1 - 先手合并两个
1 ,先手必赢。
- 先手合并两个
-
3$ 个 $1 - 先手必输,自己推一下即可。
-
4$ 个 $1 - 先手拿走一个,变成情况
4 ,先手必赢。
- 先手拿走一个,变成情况
-
5$ 个 $1 - 先手不想改变先后,合并两个,对手无论怎样一定要取走一张,此时先手拿到被动优势,先手必赢。
- 接下来的情况都可以转换成之前出现过的情况,就不往下推了。
综上所述
- 在
most>2 的前提下cnt\bmod 2=1 或者most\bmod 2=1 时先手必胜。 - 在
most\le2 的前提下cnt\bmod 3=0 先手必输。
#include <bits/stdc++.h>
using namespace std;
int T;
int n;
int main()
{
scanf("%d",&T);
for(int i=1;i<=T;i++)
{
scanf("%d",&n);
int most=0,cnt=0;
for(int x,j=1;j<=n;j++)
{
scanf("%d",&x);
if(x==1)
cnt++;
else
most+=x+1;
}
most--;
if(most<=2)
{
if(cnt%3)
printf("Case #%d: Alice\n",i);
else
printf("Case #%d: Bob\n",i);
}
else
if(cnt%2==1||most%2==1)
printf("Case #%d: Alice\n",i);
else
printf("Case #%d: Bob\n",i);
}
return 0;
}