Game of Cards 2020 CCPC 绵阳 G(博弈论+推导)

原题题面

Little Rabbit and Little Horse love playing odd card games. Now, they are playing a card game called 0123-game.
There are several cards on the table. c 0 c_0 c0​​ of them are labeled with 0 0 0, c 1 c_1 c1 of them are labeled with 1 1 1, c 2 c_2 c2​ of them are labeled with 2 2 2, and c 3 c_3 c3 of them are labeled with 3 3 3. Little Rabbit and Little Horse take turns to play the game, and Little Rabbit goes first. In each turn, the player should choose two cards on the condition that the sum of the numbers on the two cards is no more than 3 3 3, then replace these two cards with a card labeled with their sum. The player who cannot make a move loses the game.

Little Rabbit and Little Horse wonder who will win the game.

输入格式

The first line of the input contains an integer T ( 1 ≤ T ≤ 1 0 5 ) (1\leq T\leq 10^5) (1T105) − the number of test cases.
Each test case contains four integers c 0 , c 1 , c 2 , c 3 ( 0 ≤ c 0 , c 1 , c 2 , c 3 ≤ 1 0 9 ) c_0,c_1,c_2,c_3(0\leq c_0,c_1,c_2,c_3 \leq 10^9) c0,c1,c2,c3(0c0,c1,c2,c3109)− the number of cards labeled with 0 , 1 , 2 , 3 0,1,2,3 0,1,2,3.

输出格式

For the x-th test case, if Little Rabbit wins, output Case #x: Rabbit in a single line. Otherwise, output Case #x: Horse in a single line.

样例输入

2
1 1 1 1
2 2 2 2

样例输出

Case #1: Horse
Case #2: Rabbit

题面分析

小兔和小马打牌,有四种牌, c 0 c_0 c0张0牌(指牌面上数字是0,下同), c 1 c_1 c1张1牌, c 2 c_2 c2张2牌, c 3 c_3 c3张3牌,每个玩家每次取两张,要求两张数字之和不超过3,并将这两张变成一张数值为前两张之和的牌。做不到的人输,小兔先手,问谁赢谁输。

稍加分析我们可以得到几个结论(以下输赢为先手视角):

  1. 0牌和任何牌碰一起就是相当于减少一张0牌而已,因此双方可以优先碰0牌,那么等价于0牌有0张或1张 (对于0牌而言这就是个退化的巴什博弈)
  2. 在0牌碰完之后,3牌基本没啥用,但有个特殊情况需要3牌,后面会讲。
  3. 剩下的1牌,2牌很重要,首先,2牌不能碰2牌,所以优先取1牌(可以碰0,1,2),注意到可以两个1碰一个2,一个2和一个1碰一个3,一趟下来1牌少了3张,但双方度过一轮,所以等价于一个巴什博弈—— c 1 c_1 c1张牌,每次取1~2张,谁取最后谁赢,因此讨论 c 1 % 3 c_1\%3 c1%3的情况
    3.1 当0牌为0张时,
    3.1.1 c 1 % 3 = 0 c_1\%3=0 c1%3=0时显然必输
    3.1.2 c 1 % 3 = 1 c_1\%3=1 c1%3=1时,如果此时2牌数为0(也就是想取一个1和另一个2却碰不了3,只能碰两个1,但对面可以用你碰出来的2去和自己拿的一个1变成3,将必败态转换为必胜态)时必输
    3.1.3 c 1 % 3 = 2 c_1\%3=2 c1%3=2时,用两个1牌碰个2牌,就转移成了“有一个2牌,剩下都是%3=0”的,此时必败态转换为必胜态。
    3.2 当0牌为1张时,
    3.2.1 c 1 % 3 = 0 c_1\%3=0 c1%3=0时显然必胜,将0牌和1牌变为一个1牌,把3.1.1的必败态变为必胜态
    3.2.2 c 1 % 3 = 1 c_1\%3=1 c1%3=1时,如果此时2牌不为0,在3.1.2的情况下是必赢的(1碰2),但现在多了一张0牌,那必胜态变为必败态。
    3.2.3 c 1 % 3 = 2 c_1\%3=2 c1%3=2时,稍加推测可以得到,如果2牌数量至少2张必胜,反过来,不足2张就是必输
  4. 考虑到1牌数和2牌数为0的情况(只有0牌和3牌)
    4.1 3牌数为0,
    4.1.1 如果0牌数也为0(4类牌都为0),必败
    4.1.2 如果0牌数为奇数,必败
    4.2 3牌数不为0,此时要么两个0牌变一个0牌,要么一个0牌一个3牌变一个3牌,不论哪种都是消耗一个0牌,所以只要是偶数就必败

AC代码(60ms)

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5;
#define ll long long
int check(int a[5])
{
    if (a[1]==0 && a[2]==0)//只有0和3
    {
        if (a[3]==0)
        {
            if (a[0]%2==1 || a[0]==0)
                return -1;
        }
        else if (a[0]%2==0)
        {
            return -1;
        }
        return 1;
    }
    if (a[0]%2==0)
    {
        if (a[1]%3==0)
        {
            return -1;
        }
        if (a[1]%3==1 && a[2]==0)
        {
            return -1;
        }
    }
    else
    {
        if (a[1]%3==1 && a[2]>0)
        {
            return -1;
        }
        if (a[1]%3==2 && a[2]<=1)
        {
            return -1;
        }
    }
    return 1;
}
int main()
{
    int t, tot=0;
    scanf("%d", &t);
    while(t--)
    {
        int a[5];
        scanf("%d%d%d%d", &a[0], &a[1], &a[2], &a[3]);
        if (check(a)==1)
        {
            printf("Case #%d: Rabbit\n", ++tot);
        }
        else
        {
            printf("Case #%d: Horse\n", ++tot);
        }
    }
}

后记

除了情况很多,思路很绕以外没啥难的。
冷静下来推算 (指SG打表) 就能找到突破口。
DrGilbert 2020.11.7

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值