Luogu P3150 pb的游戏

题目背景

有一天 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;
}

猜你喜欢

转载自www.cnblogs.com/Mark-X/p/11699519.html
今日推荐