1. 程式人生 > >292. Nim遊戲

292. Nim遊戲

一. 題目描述

你和你的朋友,兩個人一起玩 Nim遊戲:桌子上有一堆石頭,每次你們輪流拿掉 1 - 3 塊石頭。 拿掉最後一塊石頭的人就是獲勝者。你作為先手。

你們是聰明人,每一步都是最優解。 編寫一個函式,來判斷你是否可以在給定石頭數量的情況下贏得遊戲。

示例:

輸入: 4

輸出: false 
解釋: 如果堆中有 4 塊石頭,那麼你永遠不會贏得比賽;
     因為無論你拿走 1 塊、2 塊 還是 3 塊石頭,最後一塊石頭總是會被你的朋友拿走。

二. 程式碼

class Solution {
    public boolean canWinNim(int n) {
        return n % 4 != 0;
    }
}

三. 分析

1. 程式碼異常簡單呀, 所以, 講解起來就比較有意思了。

2. 首先,我們先確認一個資訊, 假如一開始是有4個石頭的話, 那麼作為先手的, 必敗。

3. 接著,我們假如一開始有8個石頭的話,那麼作為先手,無論你一開始取多少塊石頭,後手都會取到讓石頭堆只剩下4個石頭,那麼接下來先手又需要在4個石頭中選擇取多少石頭,依舊必敗。從這裡可以推倒出,如果石頭數是4的倍數,那麼先手必敗,因為無論先手如何取,後手都能讓石頭數維持為比原先石頭數小的4的倍數上,這樣最後又會回到4這個數字上。

4. 以上是必敗的情況, 那麼剩下的不是4的倍數的情況呢? 假如一開始的石頭數不是4的倍數,且比4大,那麼,先手可以選擇去掉1-3個石頭,來讓石頭數變為4的倍數,這是因為石頭數n%4 = k,其中k \epsilon (1-3)

。那麼,先手則可以取掉k個石頭,讓石頭堆的數量變為4的倍數,讓後手陷入4的倍數的陷阱之中,真是個完美的操作。

5.綜上,只要開局不是4的倍數,先手必勝。

四. 參考