TongJI Online Judge预赛(3): Game

                             A Funny Game

Time Limit:1000MS  Memory Limit:10000K

 

Description

BirdPomelo打算玩一个有趣的游戏。在游戏开始之前,他们收集到了n枚硬币,并排成一个环,如Figure 1所示。游戏时,两人轮流拿走硬币。每一轮一个人可以移走一枚或相邻的两枚硬币,但是至少要拿走一枚。谁拿走了最后一枚硬币谁便获胜。

BirdPomelo丢硬币决定谁先拿。最后输了的人将请获胜的人吃巴比馒头和吉祥馄饨!

注意:对于n>3 我们令c1, c2, ..., cn 表示按顺时针排列的硬币。如果Bird拿走了c2,

那么c1 c3 就不相邻了!(因为c1c3之间有一个空位)

假设BirdPomelo在游戏中都使出了各自最优的拿币策略,现在你需要决定谁将赢得这个游戏。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

Input

有多组测试数据。

每组数据独占一行,包括 n1 <= n <= 106 和字符串 name,分别表示硬币的个数和

先开始游戏的人的名字(即BirdPomelo)。

    数据以一个单独的0结束,对这个0无须作任何处理。
<!--[endif]-->

Output

    对每个数据,输出赢得比赛的人的名字。

Sample Input

 

    1 Bird

    2 Pomelo

    3 Bird

    0

Sample Output

 

    Bird

    Pomelo

    Pomelo


---------------------------------------------------------------------


结论

       n<=2时,先手必胜;

       n>2时,先手必败。

 

分析

       n<=2时,先手必胜;

       n>2时,先手将环形排列的硬币拆成了链状,于是问题转化成了判断两人轮流取走一条链状硬币的胜负情况。

       对于这种子情况,先手总可以将硬币分成两堆AB,使得在堆A中的任意一条硬币链总可在堆B中找到等长的一条硬币链。简要说明如下。

       当只有一条链时,先手自然可以将这条链分成等长的两条。此时不管后手取哪条链中的硬币,先手总是在对应的另一条链中取等位置的硬币,如此反复,先前的命题便可得证。

       最后,先手将硬币取到只剩下两条硬币个数小于等于2的链时,无论后手如何取,先手终将赢得胜利。

       因此,两人轮流取走一条链状硬币,先手必胜。

       综上所述,n>2时,先手必败。


总结

       把环状拆成链状可以极大地化简本题。

在对应位上进行相同的操作亦是此类博弈问题的常用策略。

例如有道在圆形桌面上放硬币的问题。只要先手将硬币放在圆桌的正中央,随后无论后手怎么放,先手总是在他的关于圆桌中心的对称位置上放,这样先手必胜。

------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>

int main() {
    int n;
    char name[10];

    while (scanf("%d%s", &n, name), n) {
        if (n <= 2) {
            printf("%s\n", name);
        }
        else {
            if (!strcmp(name, "Bird")) {
                printf("Pomelo\n");
            }
            else {
                printf("Bird\n");
            }
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zhouyinhui/p/418122.html