经典问题:取石头 及其变式

 一堆石头,每个人每次可以取1或2个石头,直到一个人取出石头便判定其输,问n个石头是先手必胜还是后手

思路:如果先手为1或2个石头那么先手就胜利了。

反推3个石头怎么取都是1或2个石头,那么先手就输了

再反推4或5个石头可以取到3个,先手胜利

12345678910

即取3的倍数时先手必败,其他情况下先手必胜

变式:每个人每次可以取1~m个石头

同理先手1~m个石头时必胜

反推先手m + 1个石头时必败

1~mm + 1m + 2 ~ 2m + 12(m + 1)2m + 3 ~ 3m + 23(m + 1)

总结:取1~m个石头时,如果数量为(m + 1)的整数倍时先手必败,否则必胜

变式2

题目描述

牛牛和牛妹在玩游戏,他们的游戏规则是这样的:
一共有两堆石子,第一堆有 a 个,第二堆有 b 个,牛牛和牛妹轮流取石子,牛牛先手,每次取石子的时候只能从以下 2 种方案种挑一种来取(对于选择的方案数必须保证当前石子 ≥ 取的石子个数才能取):
1. 第一堆取 1个,第二堆取 2个
2. 第一堆取 2个,第二堆取 1个
谁先无法取石子,谁就输了。假设牛牛和牛妹都很聪明,请问谁会获胜?

输入描述:

第一行输入一个正整数 T(1≤T≤105)T(1 \le T \le 10^5)T(1≤T≤105) ,代表数据组数。
接下来 TTT 行,每行输入两个整数 a,b(1≤a,b≤1018)a,b (1 \le a,b\le 10^{18})a,b(1≤a,b≤1018) 代表两堆石子的数量。

输出描述:

对于每组数据,输出一行,代表胜利者的名字(牛牛获胜输出niuniu,牛妹获胜输出niumei)。

只看最小的那一堆,如果那堆为3的整数倍那么后手必胜,否则先手必胜

但是如果两堆数量相等,取a堆使a - 1为3的整数倍时,b就变成了b - 2不为3的整数倍,并且此时b - 2 为最小堆此时后手必胜

因此如果最小数量为3的倍数或两堆相等并且除3余1时后手必胜,否则先手必胜

代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long t;cin >> t;
    for(long long i = 1;i <= t;i++)
    {
        long long a,b;cin >> a >> b;
        long long mi;
        mi = min(a,b);
        if(a + b >= 3 && mi % 3 != 0)
        {
        	if(a == b && a % 3 == 1)
                cout << "niumei" << endl;
            else
                cout << "niuniu" << endl;
		}
        else
        {
            cout << "niumei" << endl;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值