问题提出:
规则:A B 两人玩取火柴的游戏,共有 21 根火柴。
每人每次最多取 4 根,最少取 1 根。取到最后一根火柴的玩家算输。
如何保证某一玩家每次都赢?
解题思路:
常胜将军 是 取火柴游戏 的一个特例。
如果每次都想让其中一个玩家赢(假设为B),那么B 要保证最后一轮剩余6根,这样不管A怎么取 都会输。
再往前推,如果上一轮 剩余 5+6 个,那么不管A怎么取,B可以取 5-A 个。
再进一步,想要占得先机,第一轮就要保证 剩余 5*k + 1 个,第一轮是关键(下手要狠呐)!
参考代码:
/* linolzhang 2009.12
Match Game
*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int main()
{
printf("请输入火柴数量:");
int N;
scanf("%d",&N);
int A = 0, B = 0;
while(true)
{
if(1 == N)
{
printf(" B获胜!\n");
break;
}
printf("你取:"); // A
A = _getch() - 48;
if(A<1 || A>4 || A>N)
{
printf("非法输入!\n");
setbuf(stdin, NULL); // 防止输入非法字符导致死循环
continue;
}
N -= A;
printf("%d 根 --> 剩余:%d根\n", A,N);
if(N == 1) // B
{
printf("你获胜!\n");
break;
}
B = (N % 5 + 4) % 5; // 争取剩余 5*k + 1
if(B == 0)
B = rand() % 4 + 1; // 被算计了,随便给一个
N -= B;
printf(" B取:%d 根 --> 剩余:%d根\n\n", B, N);
}
getchar();
return 0;
}