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
,那麼一定是先手贏。之外是後手贏。