Figure 1
Note: For n > 3, we use c1, c2, ..., cn to denote the coins clockwise and if Alice remove c2, then c1 and c3 are NOT adjacent! (Because there is an empty place between c1 and c3.)
Suppose that both Alice and Bob do their best in the game.
You are to write a program to determine who will finally win the game.
1 2 3 0Sample Output
Alice Alice Bob
《挑战程序设计竞赛》P307
题意:n枚硬币排成一个圈。Alice和Bob轮流从中取一枚或两枚硬币。不过,取两枚时,所取的两枚硬币必须是连续的。硬币取走之后留下空位,相隔空位的硬币视为不连续的。Alice开始先取,取走最后一枚硬币的一方获胜。当双方都采取最优策略时,谁会获胜?
解题思路:
n高达1000000,考虑到还有将连续部分分裂成几段等的情况,状态数非常地多,搜索和动态规划法难以胜任。需要更加巧妙地判断胜败关系。
首先,试想一下如下情况。能够把所有的硬币分成像下图这样的两个完全相同的组的状态,是必胜状态?还是必败状态?(没有图 图详见P307 0.0)
事实上这是必败态。不论自己采取什么选取策略,对手只要在另一组采取相同的策略,就又回到了分成两个相同的组的状态。
必定能够再次回到同样的情况:不论自己取走哪些硬币-->如果对手也取走对应的硬币-->则回到同样的情况
不断这样循环下去,总会在某次轮到自己时没有硬币了。也就是说,因为对手取走了最后一枚硬币而败北。
接下来,让我们回到正题。Alice在第一步取走了一枚或两枚硬币之后,原本成圈的硬币就变成了长度为n-1或是n-2的链。这样只要Bobby在中间位置,根据链长的奇偶性,取走一枚或两枚硬币,就可以把所有硬币正好分成了两个长度相同的链。
这正如我们前面所讨论的一样,是必败态。也就是说,Alice必败,Bob必胜。只不过,当n<=2时,Alice可以在第一步取光,所以胜利的是Alice。在这类游戏中,作出对称的状态后再完全模仿对手的策略常常是有效的。
AC代码:
#include<stdio.h>
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
if(n<=2) printf("Alice\n");
else printf("Bob\n");
}
return 0;
}