取石子兒和拿撲克牌問題

2021-06-06 14:58:17 字數 2335 閱讀 1991

tang

和jiang

非常喜歡玩一種有趣的小遊戲:有

n個石子,兩人輪流從中取出1個

, 3個或

4個石子,當石子被取空時,遊戲結束。最後乙個取石子的人獲勝

,第一次總是

tang取.

當然,他們倆都足夠聰明,總會採取最優的策略。

演算法思想(使用遞迴):

當剩餘為1、3

、4的時候先手者必勝;如果當前數目不是這三個數字,則遞迴採用去1或

3或4,只要其中有一種方式使得剩下的字兒使對方輸,則先手者必勝;否則後手者勝。**如下:

#include using namespace std;

bool win(int n)

int main()

上面的方法時間複雜度太高,那麼是否能夠通過對當前一輪石頭總數的判斷,可以知道是當前玩家贏

(先手贏

),還是下一輪的玩家贏

(後手贏)呢

?

我們可以發現,凡是mod 7

餘2或0的石頭數目,都是後手贏,其他情況都是先手贏。我們來證明一下:

(1) stonenum=1,2,3,4

時就不證明了。

(2)

當stonenum=2的時候,是player2贏。我們能夠想到,如果player1抽取石頭後,能使得player2玩的時候手頭上的石頭數量為2。那麼player1一定贏。也就是說(2+1=3),(2+3=5),(2+4=6)的石頭數量一定導致player1贏。

(3)

當stonenum=7的時候,player1無論抽1,3,4塊石頭中的任意情況,都會使得player2玩的時候手頭上的石頭數量為6,4,3。這三種石頭數量都是當前玩家贏(player2贏)。因此7塊石頭一定是player2贏。

(4)

當stonenum=7的時候,情況與(2)相同。因此(7+1=8),(7+3=10),(7+4=11)的石頭數量一定是player1贏。

(5)

當stonenum=9的時候,情況與(3)相同。因此9塊石頭一定是player3贏。

(6)

依次下去,我們就能夠得出這個結論:

策略:如果當前石頭數量stonenum%7==2||stonenum%7==0

,那麼一定是後手贏。除此之外是先手贏。

從這道題目又想到了以前看到的乙個題目:

假如有10

枚硬幣,由你和對手兩個人輪流拿,每次只能拿1個、

2個或4個;拿走最後一枚硬幣的人,算輸。請問:有沒有必贏的可能?

演算法思想(使用遞迴):

當剩餘為1、2

、4的時候先手者必勝;如果當前數目不是這三個數字,則遞迴採用去1或

2或4,只要其中有一種方式使得剩下的字兒使對方輸,則先手者必勝;否則後手者勝。**如下:

#include using namespace std;

bool win(int n)

int main()

同樣如果按照上面分析數字的方法來分析則會非常簡單:

我們可以發現,如果剩餘的數字是

3的整倍數的時候則先手輸,若當前數目模3後余

1、2、

4,則先手贏:

(1) num=1,2,4

時就不證明了。

(2)

當stonenum=3的時候,是player2贏。我們能夠想到,如果player1抽取石頭後,能使得player2玩的時候手頭上的石頭數量為3。那麼player1一定贏。也就是說(3+1=4),(3+2=5),(3+4=7)的石頭數量一定導致player1贏。

(3)

當stonenum=6的時候,player1無論抽1,2,4塊石頭中的任意情況,都會使得player2玩的時候手頭上的石頭數量為5,4,2。這三種石頭數量都是當前玩家贏(player2贏)。因此6塊石頭一定是player2贏。

(4)

當stonenum=9的時候,情況與(2)相同。

(6)

依次下去,我們就能夠得出這個結論:

策略:如果當前石頭數量

stonenum%3==1||stonenum%3==2||stonenum%3==4

,那麼一定是先手贏。之外是後手贏。