一堆石头,每个人每次可以取1或2个石头,直到一个人取出石头便判定其输,问n个石头是先手必胜还是后手
思路:如果先手为1或2个石头那么先手就胜利了。
反推3个石头怎么取都是1或2个石头,那么先手就输了
再反推4或5个石头可以取到3个,先手胜利
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
即取3的倍数时先手必败,其他情况下先手必胜
变式:每个人每次可以取1~m个石头
同理先手1~m个石头时必胜
反推先手m + 1个石头时必败
1~m | m + 1 | m + 2 ~ 2m + 1 | 2(m + 1) | 2m + 3 ~ 3m + 2 | 3(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;
}
}
}