「反Nim」数列游戏
本题为12月27日22寒假集训每日一题题解
题目来源:(未知)
题面
题目描述
cad和jyx最近迷上了一款名为插入数列的游戏,有一个n行m列的网格,你每次可以按下1个或多个格子,但必须要在同一列且连续,已经按过的地方不可以再按,谁按下最后一个格子,谁就输了,刚开始的时候互有胜负,但玩过几把之后两个人慢慢的就知道了自己最优的走法是什么,现在问题来了,给你n和m你能告诉我谁会赢吗?(cad先手)
输入
多组测试样例
每组测试样例两个数分别表示行和列(n,m<=1e5)
输出
输出赢的人的名字
样例输入
1 1
样例输出
jyx
思路分析
显然,这是一个反Nim问题,列为堆,行为堆里元素的个数,直接套用反Nim问题的结论即可.
反Nim问题的结论:
当至少一堆大于1时,与Nim问题一致 异或和为0,必败;异或和不为0,必胜
当每一堆都是1时,与Nim问题相反 异或和不为0,必败;异或和为0,必胜
不过由于这里每一堆里元素的个数都是相同的,所以异或和可以直接用行的奇偶性代替(奇即异或和非0,偶即异或和为0).
参考代码
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
// 输入数据
int n, m;
while(cin >> n >> m)
{
// 反Nim问题的特殊情况
if(n == 1)
{
m += 1; // +1使得奇偶性发生颠倒,即对Nim问题结论取反
}
// Nim问题结论
if(m % 2)
{
cout << "cad\n";
}
else
{
cout << "jyx\n";
}
}
return 0;
}
"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德
这里是浙江理工大学22届ACM集训队的成员一枚鸭!
本文首发于博客园,作者:星双子,除了我自己的转载请注明原文链接:https://www.cnblogs.com/geministar/p/zstu22_12_27.html