問題:
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.
大意:
你和你的一個(gè)朋友玩一個(gè)游戲:在一個(gè)桌子上有一堆石頭图张,每個(gè)人每次可以從中拿1個(gè)或2個(gè)或3個(gè)石頭木柬,你和你朋友兩個(gè)人輪流拿芙粱,誰拿走的桌上最后一波石頭韩玩,誰就贏了乎芳。你先拿。
假設(shè)你和你的朋友都會采取最佳策略逻翁。寫一個(gè)函數(shù)來判斷對于給出的一個(gè)數(shù)量的石頭龙填,你會不會贏失仁。
比如說尸曼,如果桌上有4個(gè)石頭,那么你肯定輸萄焦,無論你先拿1個(gè)還是2個(gè)還是3個(gè)控轿,最后一波石頭總是被你朋友拿走的。
思路:
乍一看好像不遞歸不可能判斷出來拂封,但其實(shí)演算一下茬射,發(fā)現(xiàn)是有規(guī)律可行的。
- 首先當(dāng)石頭數(shù)量是3個(gè)以下時(shí)冒签,你肯定會贏在抛。
- 當(dāng)石頭數(shù)量為4個(gè)時(shí),你肯定輸萧恕。
- 當(dāng)石頭數(shù)量為5刚梭、6肠阱、7個(gè)時(shí),你總是可以拿到桌上只剩4個(gè)朴读,那對于你朋友來說屹徘,他面對4個(gè)石頭,上面說了磨德,一定會輸缘回,所以你一定會贏。
- 當(dāng)石頭數(shù)量是8個(gè)時(shí)典挑,你不管怎么拿,最終桌上只會剩下5啦吧、6您觉、7三種情況,那么此時(shí)你朋友面對的就是情況3授滓,他就一定贏琳水,而你一定輸。
- 當(dāng)石頭數(shù)量是9般堆、10在孝、11時(shí),你總是可以把石頭拿到只剩8個(gè)淮摔,那么此時(shí)你朋友面對的就是情況4私沮,那他就一定輸,而你一定贏和橙。
……
這樣分析一下仔燕,規(guī)律就出來了,只要你面對的石頭數(shù)量是4的倍數(shù)魔招,那你就一定會輸晰搀,此外,你全都可以贏办斑,贏面還是很大啊哈哈外恕。代碼也呼之欲出了。
代碼(C++):
class Solution {
public:
bool canWinNim(int n) {
return n % 4 == 0 ? false : true;
}
};
示例工程:https://github.com/Cloudox/NimGame
合集:https://github.com/Cloudox/LeetCode-Record