博弈 取 2堆 石子遊戲

2021-08-07 20:18:41 字數 1430 閱讀 6655

題目:

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

input

輸入包含若干行,表示若干種石子的初始情況,其中每一行包含兩個非負整數a和b,表示兩堆石子的數目,a和b都不大於1,000,000,且a<=b。a=b=0退出。

output

輸出也有若干行,如果最後你是敗者,則為0,反之,輸出1,並輸出使你勝的你第1次取石子後剩下的兩堆石子的數量x,y,x<=y。如果在任意的一堆中取走石子能勝同時在兩堆中同時取走相同數量的石子也能勝,先輸出取走相同數量的石子的情況.

sample input

1 2 

5 84 7

2 20 0

sample output

0

14 7

3 50

10 0

1 2

題意&分析:

這個是威佐夫博奕(wythoff game參考資料傳送門),題目是個wythoff博弈,贏的話要輸出第一次取完後剩下的石子數目。

根據已知的結論:兩個人如果都採用正確操作,那麼面對非奇異局勢,先拿者必勝;反之,則後拿者取勝。

所以設初始為(a,b)且a<=b,情況如下:

1、如果(a,b)為奇異局勢,那麼先手輸,判斷的方法是利用

「 ak =[k(1+√5)/2],bk= ak + k (k=0,1,2,…,n 方括號表示取整函式) 「,先求出兩者的差作為k,去判斷a是不是滿足結論,即a==aj;

2、如果a=0,先手贏;

2、如果(a,b)非奇異局勢,那麼可以改變成奇異局勢,這樣先手 贏,我們只需要從b中取出適當數目的石子求出新的aj,並且將初始的a賦給b,這樣就構造出來奇異局勢,後手的人輸。需要多判斷一步是否可以同時取一樣數目的構造方法。

**如下:

#include 

#define inf 0x3f3f3f3f

#define test cout<<"stop here"namespace

std;

typedef

long

long ll;

const ll mod = 1e9 + 7;

int main()}}

}return

0;}

取 2堆 石子遊戲

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

hdu 2177 取 2堆 石子遊戲 博弈

題意 有兩堆石子,兩人輪流取石子,輪到某人時,有兩種取法,要麼從兩堆石子中同時取出一定數量的石子,要麼只從一堆中取任意數量的石子,不能不取。不能取的人判為輸。普通思想 對於博弈問題,首先想到的就是sg函式。所以我們先從小到大的看局面。可以得出,對於每一種狀態 x,y x,y為石子堆。要麼 x,y 本...

博弈 取石子遊戲

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