题目背景
有一天 pb和zs玩游戏 你需要帮zs求出每局的胜败情况
题目描述
游戏规则是这样的: 每次一个人可以对给出的数进行分割,将其割成两个非零自然数,之后由另一个人选择留下两个数中的其中一个;之后由另一个人进行分割这个剩下的数,重复步骤……
当一个人无法对数进行分割的时候游戏结束,另一个人获胜
现在要你求出N次游戏的胜败
每局由pb先进行分割,如果pb赢输出"pb wins" 如果zs赢输出"zs wins"
注:双方都是绝顶聪明的
输入格式
第一行一个数N,表示数据组数
之后N行,每行一个数M,表示每局初始的数
输出格式
共N行,每行一串字符 表示游戏结果
输入样例
5
1
3
7
20
5
输出样例
zs wins
zs wins
zs wins
pb wins
zs wins
说明
\(1<N<50\)
\(1\leqslant m \leqslant 1000000000\)
首先呢这一道博弈论,说实话博弈论我也不会
所以这篇题解也就是提供一个大概的思路,并没有严格的证明
首先\(N\)的范围很小,我们就是不考虑了,就当是个常数吧
呢么对于每一轮游戏来说,都有\(k\)次回合,所以我们对于每次回合来说就好了
如果\(m=2\)呢么我们都选择就只能是把他分成两个\(1\)
如果\(m=1\)呢么就不能继续分解也就是说这个回合的人输了
由于两个人都是“聪明绝顶”,所以对于自己的回合一定是会分解出一个让对手必输的数也就是\(1\)
所以对于一个数\(m\),两个人的选择都是把这个数分解成\(m-1\)和\(1\)
呢么对已一开始的数\(m\)如果是偶数后手一定赢,反之先手赢
先手每次都是\(pb\),所以这就是一道判断奇偶数的题
coding
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
register int x = 0;
register char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9')
{
x = (x<<3)+(x<<1) + ch-'0';
ch = getchar();
}
return x;
}
int main()
{
for(register int i = read();i >= 1;i--)
{
register int x = read();
if(x&1) puts("zs wins");
else puts("pb wins");
}
return 0;
}