Leetcode—292
Nim Game
You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.
Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.
For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend
简单博弈
【题目大意】:两个足够聪明的人玩拿石头的游戏,你先开始,每次每个人可以拿1至3个石头,谁拿走最后一个石头谁就获胜,问给定n个石头的情况下,你能不能获胜
【解答】:
当n=1时,直接拿1个,显然可以获胜;
当n=2时,直接拿2个,显然可以获胜;
当n=3时,直接拿3个,显然可以获胜;
当n=4时,不管拿1个, 2个,或者3个,第4个都会被另一个人拿走,所以无法获胜;
当n=5时,我为了拿到最后一个石头,要使对方陷入我刚刚n=4时的困境,也就是要让对方不管是拿1个,2个,还是3个,都无法拿走最后一个石头,那么,我可以把我在n=4时遇到的困境转移给对方,现在有5个石头,我可以通过拿走一个石头,使得对方陷入我刚刚n=4时遇到的困境,当我拿走1个的时候,对方面临着4个石头,不管拿1个, 2个,或者3个,第4个都会被我拿走,所以我可以获胜;
当n=6时,显然可以采取类似于n=5时的做法,我先取走2个,使得剩下的为4,无论对方怎么拿,最后一个石头都是我的;
当n=7时,我先取走3个,使得剩下的为4,无论对方怎么拿,最后一个石头都是我的;
当n=8时,由于对方也是很聪明的人,他也会尽量使我陷入面临n=4那种困境,为了使得我面临困境,如果我拿1个,对方就拿3个,使我面临n=4的困境,如果我拿2个,对方就拿2个,使我面临n=4的困境,如果我拿3个,对方就拿1个,使我面临n=4的困境,最终我无法获胜;
当n=9时,
……
观察以上过程,当一个人面临的石头个数n是4的倍数的时候,他就会输,所以为了使自己获胜,应该尽量使得对方的陷入n是4的倍数的困境
因此:
如果初始的石头个数n是4的倍数,那么不管我拿几个,对方就拿相应4的补数(我拿1,他就拿3,我拿2,他就拿2,我拿3,他就拿1),这样子我最后总会面临n=4的困境,所以我会输;
如果初始的石头个数n不是4的倍数,那么我可以先拿n%4个,使对方陷入面临n为4的倍数的困境,所以我会赢。
结论,当初始n是4的倍数的时候,我会输,否则,我会赢。
【AC代码】:
#include <stdio.h>
bool canWinNim(int n) {
if(n % 4 == 0){
return false;
}
else{
return true;
}
}