《程式設計之美》1.11節介紹了乙個取石頭的遊戲,遊戲規則如下:n個石頭排成一行,兩個玩家依次取石頭,每次可以取一塊或者相鄰的兩塊,取到最後一塊石頭的獲勝。如果a方先手,如何保證自己獲勝?
書中給出了乙個a必勝的方案,如果總共有奇數個石頭,a取走中間的一塊,如果總共有偶數塊石頭,a取走中間的兩塊,這樣石頭將變成對稱的兩堆,a只要按照和對手對稱的方法選取,最終總是可以取到最後一塊石頭,從而保證獲勝。
書中還給了乙個擴充套件問題:如果取到最後石頭的人判輸,a應該如何應對?
很容易可以推導出a在1塊石頭的情況下必輸,2、3塊時必勝,4時必輸,在此基礎上可以推導出5、6時必勝(因為a首先取走邊上的1塊或2塊石頭就變成了4塊,此時b先手必輸);於是網上許多文章認為石頭總數為3k+1時a必輸,其它時候必勝。
其實這個過程是錯誤的,大部分認為7塊石頭a必輸的推導過程,都是說a取走一塊或兩塊之後變成了5塊或6塊石頭,而這是乙個對方先手必勝的局面,這裡的推導過程顯然忽視了連續性這個問題,a如果不是從邊緣而是從中間的某個位置取走一塊石頭,則剩餘石頭就變成了非連續的6塊石頭,前面的結論就未必成立了,因此這裡的推導在邏輯上是有漏洞的。
實際上,對於7塊石頭,存在著a先手必勝的方案,那就是取走中間的一塊,這樣總的石頭就變成了分離的兩部分,每邊3塊,這時b有幾種可能的策略:
1) 在任意一堆,取走邊上的一塊,這時a取走另外一堆邊上的一塊,變成2*2的兩堆;如果b取走其中1塊,a取走另外一方的兩塊,則a勝,如果b取走一方的兩塊,a取走另外一方的1塊,也是a勝;
2) 在任意一堆取走中間的一塊,這時a取走另外一堆相鄰的兩塊,剩餘三個不連續的石子該b取,a勝;
3) 在任意一堆取走連續的兩塊,這時a取走另外一堆中間的一塊,同樣變成剩餘三個不連續的石子該b取,還是a勝;
同樣的,對於8塊石頭的情況,a先手取走中間的兩塊,後面的過程和7塊石頭相同,也是a必勝。
至於9個以及更多石頭的方案,留待後續研究。
一排石頭的遊戲(續)
我們繼續分析9棵石頭的情況,在正式開始研究之前,讓我們先研究幾種簡單的情況。前面的分析中我們已經研究了幾種先手必輸的方案,包括1,4,2 2 其中 表示不連續的兩堆或多堆 3 3。我們另外引入幾個新的先手必輸的方案,分別是 1 2 3 假設a先取,a所有可能的取法包括 1 取走1,變成2 3,相當於...
「拈」遊戲系列一 一排石頭的遊戲
這個題目來自於程式設計之美上的nim 1 一排石頭的遊戲,該類問題能考察面試者的思維,往往是兩個人玩的乙個遊戲,具體形式公司可以具體設定,這裡題目的意思是取石頭的數目有規定,也可以使報數每次只能增加幾個數字等。該類題目往往是要把最後乙個取完石頭定位為贏或者輸。該類題目第乙個取石頭的人占有主動權也有被...
一排石頭的遊戲(取石頭)C語言實現
問題描述 n塊石頭排成一行,每塊石頭有各自固定的位置。兩個玩家依次取石頭,每個玩家可以取其中任意一塊石頭,或者相鄰的兩塊石頭,石頭在遊戲過程中不移位。最後能將石頭一次取光的玩家獲勝。c語言實現 此處簡化,將石頭數設定為5,用乙個長度為5的陣列表示石頭,當元素值為1的時候,代表有石頭。為0時,代表沒有...