题目
链接:https://ac.nowcoder.com/acm/problem/247578
来源:牛客网题目描述
牛牛和牛妹在玩游戏,他们的游戏规则是这样的:
一共有两堆石子,第一堆有 aaa 个,第二堆有 bbb 个,牛牛和牛妹轮流取石子,牛牛先手,每次取石子的时候只能从以下 222 种方案种挑一种来取(对于选择的方案数必须保证当前石子 ≥\ge≥ 取的石子个数才能取):
\1. 第一堆取 111 个,第二堆取 222 个
\2. 第一堆取 222 个,第二堆取 111 个
谁先无法取石子,谁就输了。假设牛牛和牛妹都很聪明,请问谁会获胜?输入描述:
第一行输入一个正整数 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)。
示例1
输入
[复制](javascript:void(0)😉
2 1 2 3 3
输出
[复制](javascript:void(0)😉
niuniu niumei
思路 博弈-对称策略
不考虑玩家1取什么棋子,玩家二只要和其策略不同,便可以使一个回合(两个人都下了棋)后,两堆石子总数都减3,那么我们考虑\(min(a, b)\), 只要若干回合后,棋子a和b都减少3,所以\(min(a, b)\)石子提前捡到0,那么p1必败。所以若\(min(a,b)\) % 3 == 0,则玩家2只要对称下就能赢,若\(min(a, b)\) % 3 > 0,则玩家1可以构造出必败棋给玩家2,玩家1能赢。
若玩家1构造不了必败棋,即选哪个策略都是\(min(a, b) % 3\)都大于0,那么相当于丢给玩家2的一定是必胜棋了,此时玩家1必败,否则相反面等于0,丢给玩家2的一定是必败棋,玩家1必胜。
Code
#include <iostream>
#define xian puts("niuniu")
#define hou puts("niumei")
using namespace std;
int main() {
int t;
cin >> t;
while(t --) {
long long a, b;
cin >> a >> b;
// 1,2 1,1 同样满足所以不考虑边界
if(min(a - 1, b - 2) % 3 == 0 || min(a - 2, b - 1) % 3 == 0) xian;
else hou;
}
}