《遊戲》 取石子

2021-08-30 16:04:04 字數 2268 閱讀 3326

tang和jiang非常喜歡玩一種有趣的小遊戲: 有n個石子,兩人輪流從中取出1個, 3個或4個石子,當石子被取空時,遊戲結束。最後乙個取石子的人獲勝, 第一次總是tang取. 當然,他們倆都足夠聰明,總會採取最優的策略。

input

每行會有乙個正整數n(n<=100000), 代表石子的個數, n=0 代表輸入結束

output

輸出獲勝人的名字。

sample input

1 //石頭數量為1 20

sample output

tang //石頭數量為1的時候,總是tang會贏

jiang

分治法: 窮舉出所有可能的取石頭方案。

演算法思想,假設兩個玩家分別pid編號為0和1。f(n, pid)表示當前一輪獲勝的玩家編號(如果f=0,表示獲勝玩家是0),其中n表示當前一輪的石頭總數,pid表示當前一輪的玩家標號。

1、當前一輪玩家pid=0,那麼他取石頭的可能性為1,3或4。則下一輪玩家pid=1的情況有三種: f(n-1, 1),f(n-3,1),f(n-4,1)。如果這三種情況的f()函式值至少有乙個是0,不妨假設f(n-1, 1)=0,根據題目條件的"他

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

" ,那麼當前一輪pid=0的玩家一定會選擇取1個石頭,結果也一定是pid=0贏。

因此當pid=0時, f(n ,0)=f(n-1, 1)&f(n-3, 1)&f(n-4, 1)

2、當前一輪玩家pid=1,那麼下一輪三種情況下只要有乙個f()函式值為1,則結果一定是pid=1贏。即

當pid=1是, f(n ,1)=f(n-1, 0)|f(n-3, 0)|f(n-4, 0)

下面是源**:

public class recurstoneplay ;

/*** 當前輪到第pidx個player從剩下的stonenum塊石頭中取石頭獲勝的情況

* @param stonenum 當前石頭總數

* @param pidx 取石頭的人的id

* @return 在當前這種情況下,能夠取勝的player的id

*/public static int turn(int stonenum,int pidx)

//測試

public static void main(string args)

}

上面的方法時間複雜度太高,那麼

是否能夠通過對當前一輪石頭總數的判斷,可以知道是當前玩家贏(先手贏),還是下一輪的玩家贏(後手贏)呢? 

我們假設先手玩家是player1,後手玩家是player2。用上面的程式執行1-30個石頭,並輸出贏的情況(其中0代表player1贏,1代表player2贏)。

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27   28  29  30

0  1   0  0  0  0  1   0  1    0    0    0    0    1    0    1     0    0    0    0    1     0    1     0    0    0    0      1    0    1

我們可以發現,凡是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,那麼一定是後手贏。除此之外是先手贏。

取石子遊戲

如下 include include intmain k b a temp floor k 1.0 sqrt 5 2.0 if temp a printf 0 n else printf 1 n return 0 一 巴什博奕 bash game 只有一堆n個物品,兩個人輪流從這堆物品中取物,規定每...

取石子遊戲

有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子 二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。現在給出初始的兩堆石子的數目,如果輪到你先取,假設雙方都採取最好的策略,問最後你是勝者還是敗者。in...

取石子遊戲

取石子遊戲 time limit 1000ms memory limit 10000k total submissions 25176 accepted 7961 description 有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆...