博弈 取石子遊戲

2021-07-13 08:14:51 字數 1341 閱讀 2794

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

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

output輸出對應也有若干行,每行包含乙個數字1或0,如果最後你是勝者,則為1,反之,則為0。

sample input2 18 44 7

sample output

010

前幾個必敗點如下:(0,0),(1,2),(3,5),(4,7),(6,10),(8,13)……可以發現,對於第k個必敗點(m(k),n(k))來說,m(k)是前面沒有出現過的最小自然數,n(k)=m(k)+k。乙個必敗點有如下性質:

1.所有自然數都會且僅會出現在乙個必敗點中;

證明:m(k)是前面沒有出現過的最小自然數,自然與前k-1個必敗點中的數字都不同;m(k)>m(k-1),否則違背m(k-1)的選擇原則;n(k)=m(k)+k>m(k-1)+(k-1)=n(k-1)>m(k-1),因此n(k)比以往出現的任何數都大,即也沒有出現過。又由於m(k)的選擇原則,所有自然數都會出現在某個必敗點中。性質1證畢。

2.規則允許的任意操作可將必敗點移動到必勝點;

證明:以必敗點(m(k),n(k))為例。若只改變兩個數中的乙個,由於性質1,則得到的點一定是必勝點;若同時增加兩個數,由於不能改變兩數之差,又有n(k)-m(k)=k,故得到的點也一定是必勝點。性質2證畢。

3.一定存在規則允許的某種操作可將必勝點移動到必敗點;

證明:以某個必勝點(i,j)為例。因為所有自然數都會出現在某個必敗點中,故要麼i等於m(k),要麼j等於n(k)。若i=m(k),j>n(k),可從j中取走j-n(k)個石子到達必敗點;若i=m(k),jm(k),j=n(k),可從i中取走i-m(k)個石子到達必敗點;若i判斷乙個點是不是必敗點的公式與**分割有關,為:

m(k) = k * (1 + sqrt(5))/2

n(k) = m(k) + k

至於為什麼如此,我就不知道了,也沒有查到,很好奇。

poj1067就是這道題,**如下:

#include #include using namespace std;

int main()

int k = n - m;

double data = floor(k*(1.0+sqrt(5.0))/2.0);

if (data == m)

cout<<0<

簡單取石子遊戲 博弈

很坑爹的小遊戲,至於怎麼坑爹,嘎嘎 自己研究去吧 include include include include includeusing namespace std void loc int x,int y 定位游標 void welcome 建立歡迎介面 void buildmap 建立介面 v...

題解 取石子遊戲(博弈)

題目描述 一天小明和小紅在玩取石子遊戲,遊戲規則是這樣的 1 本遊戲是乙個二人遊戲 2 有一堆石子,共有n個 3 兩人輪流進行 4 每走一步可以取走1 m個石子 5 最先取光石子的一方為勝。如果遊戲的雙方使用的都是最優策略,請輸出哪個人能贏。輸入輸入的第一行是乙個正整數c c 100 表示有c組測試...

博弈 取 2堆 石子遊戲

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