A Funny Game<?xml:namespace prefix = o />
Time Limit:1000MS Memory Limit:10000K
【Description】
Bird和Pomelo打算玩一个有趣的游戏。在游戏开始之前,他们收集到了n枚硬币,并排成一个环,如Figure 1所示。游戏时,两人轮流拿走硬币。每一轮一个人可以移走一枚或相邻的两枚硬币,但是至少要拿走一枚。谁拿走了最后一枚硬币谁便获胜。
Bird和Pomelo丢硬币决定谁先拿。最后输了的人将请获胜的人吃巴比馒头和吉祥馄饨!
注意:对于n>3, 我们令c1, c2, ..., cn 表示按顺时针排列的硬币。如果Bird拿走了c2,
那么c1和 c3 就不相邻了!(因为c1和c3之间有一个空位)
假设Bird和Pomelo在游戏中都使出了各自最优的拿币策略,现在你需要决定谁将赢得这个游戏。
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
【Input】
有多组测试数据。
每组数据独占一行,包括 n(1 <= n <= 106) 和字符串 name,分别表示硬币的个数和
先开始游戏的人的名字(即Bird或Pomelo)。
数据以一个单独的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时,先手将环形排列的硬币拆成了链状,于是问题转化成了判断两人轮流取走一条链状硬币的胜负情况。
对于这种子情况,先手总可以将硬币分成两堆A和B,使得在堆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;
}