取石子游戲


取石子游戲

 

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 29247   Accepted: 9575

 

Description

 

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

 

Input

 

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

 

Output

 

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

 

Sample Input

 

2 1
8 4
4 7

 

Sample Output

0
1
0

 

分析:這是威佐夫問題,學習了

轉自http://yjq24.blogbus.com/logs/42826226.html 

大致上是這樣的:有兩堆石子,不妨先認為一堆有10,另一堆有15個,雙方輪流取走一些石子,合法的取法有如下兩種:

1)在一堆石子中取走任意多顆;

2)在兩堆石子中取走相同多的任意顆;

約定取走最后一顆石子的人為贏家,求必敗態(必勝策略)。

這個可以說是MR.Wythoff(Wythoff於1907年提出此游戲)一生全部的貢獻吧,我在一篇日志里就說完有點殘酷。這個問題好像被用作編程競賽的題目,網上有很多把它Label為POJ1067,不過如果學編程的人不知道Beatty定理和Beatty序列 ,他們所做的只能是找規律而已。不熟悉的人可以先在這里 玩幾局~

簡單分析一下,容易知道兩堆石頭地位是一樣的,我們用余下的石子數(a,b)來表示狀態,並畫在平面直角坐標系上。

用之前的定理: 有限個結點的無回路有向圖有唯一的核  中所述的方法尋找必敗態。先標出(0,0),然后划去所有(0,k),(k,0),(k,k)的格點;然后找y=x上方未被划去的格點,標出(1,2),然后划去(1,k),(k,2),(1+k,2+k),同時標出對稱點(2,1),划去(2,k),(1,k),(2+k,1+k);然后在未被划去的點中在y=x上方再找出(3,5)。。。按照這樣的方法做下去,如果只列出a<=b的必敗態的話,前面的一些是(0,0),(1,2),(3,5),(4,7),(6,10),…

接下來就是找規律的過程了,忽略(0,0),記第n組必敗態為(a[n],b[n])

命題一:a[n+1]=前n組必敗態中未出現過的最小正整數

[分析]:如果a[n+1]不是未出現的數中最小的,那么可以從a[n+1]的狀態走到一個使a[n+1]更小的狀態,和我們的尋找方法矛盾。

命題二:b[n]=a[n]+n

[分析]:歸納法:若前k個必敗態分別為 ,下證:第k+1個必敗態為

從該第k+1個必敗態出發,一共可能走向三類狀態,從左邊堆拿走一些,從右邊堆拿走一些,或者從兩堆中拿走一些.下面證明這三類都是勝態.

情況一:由命題一,任意一個比a[k+1]小的數都在之前的必敗態中出現過,一旦把左邊堆拿少了,我們只要再拿成那個數相應的必敗態即可。

情況二(從右邊堆拿走不太多):這使得兩堆之間的差變小了,比如拿成了 ,則可再拿成

情況二(從右邊堆拿走很多):使得右邊一堆比左邊一堆更少,這時類似於情況一,比如拿成了 (其中a[m] ;

情況三:比如拿成 ,則可再拿成

綜上所述,任何從 出發走向的狀態都可以走回核中.故原命題成立.

以上兩個命題對於確定(a[n],b[n])是完備的了,給定(0,0)然后按照這兩個命題,就可以寫出(1,2),(3,5),(4,7),…

這樣我們得到了這個數列的遞推式,以下我們把這兩個命題當成是(a[n],b[n])的定義。

先證明兩個性質:

性質一:核中的a[n],b[n]遍歷所有正整數。

[分析]:由命題一,二可得a[n],b[n]是遞增的,且由a[n]的定義顯然。

性質二:A={a[n]:n=1,2,3,…},B={b[n]:n=1,2,3,…},則集合A,B不交。

[分析]:由核是內固集,顯然。

看到這里大家有沒有想到Beatty序列呢,實際上a[n]和b[n]就是一個Beatty序列。

,有 ,解方程

,到此,我們找到了該必敗態的通項公式。

實際上這組Beatty序列還有一些別的性質,比如當一個數是Fibonacci數的時候,另一個數也是Fibonacci數;而且兩者的比值也越來越接近黃金比,這些性質在得到通項公式之后不難證明。

總的來說,這個問題給我們了哪些啟示呢?首先用定理所說的方法找核,然后給出核的規律(遞推,或是通項)並且證明。最后附上一張對應的必敗態圖.

wythoff

轉自http://yjq24.blogbus.com/logs/42653430.html

 

上次說了勝態和必敗態,還記得最后的練習么?桌子上有15個石子,每人每次可以拿去1個或3個石子,拿走最后一個石子的人贏,列出所有的必敗態:0,2,4,6,8,10,12,14。說過了狀態作為結點可以畫一張有向圖,下面這張圖就是這個游戲所對應的:

 

 

 

dg1 我只列了不大於6的狀態,回顧一下勝態和必敗態的性質:

勝態一定可以通過某種策略走向必敗態;而必敗態采取任何策略都將走向勝態。


用圖論的話來說,
因為必敗態只能走向勝態,所以任何兩個必敗態結點之間不可能存在邊;
因為勝態總能走到必敗態,所以對任何一個非必敗態的結點,一定存在一個從它指向必敗態結點的邊。

不妨看看左圖中的0,2,4,6,親自體會一下。



定義:有向圖中,集合X中任意兩點之間無邊,稱集合X為內固集。
定義:
有向圖中,任意不在集合X中的點存在一條指向集合X的邊,稱集合X為外固集。

定義:有向圖中,集合X 既是外固集,又是內固集,稱集合X為核。



顯然,內,外固集的定義正好針對上面的兩句話,而核就是包含所有必敗態的集合。



定理:雙人博弈中,約定走最后一步為勝,如果有核存在,則其中一方有不敗策略。

證明:不妨設A先行動,初始狀態不在核中,由於核是外固集,A一定可以采取某種策略把狀態走到核中,然后輪到B;由於核是外固集,所以B不管采取什么策略,都將走出核,所以輪到A的時候,A又可以把狀態走進核里。總而言之,A可以使B永遠面臨核內的狀態。無路可走的狀態不可能在核外,因為核外總能走到核內,A可以保持不敗。如果初始狀態不在核中,那么利用同樣的想法易知B有不敗策略。



以上的定理意義是非凡的,雖然這個定理在證明之前我們其實就已經了解了核與必敗態的緊密聯系。那么,對一個博弈游戲來說,找出核是核心問題。在此之前,先得考察核得存在性:

 

 

 

定理:有限個結點的無回路有向圖有唯一的核。

 

證明:核可以用如下的方式找出:首先找出沒有后繼結點的點集P[1](最基本的必敗態,比如上圖中的結點0)然后找到那些指向P[1]的結點集合為N[1](最基本的勝態,比如上圖的結點1和結點3)然后,除去P[1]和N[1]中的點並除去和這些點關聯的邊,繼續尋找沒有后繼結點的點集P[2](更高級的必敗態,比如上圖中的結點2),依次類推,則最后的核為P=P[1]並P[2]並…並P[n]。

 

很容易說明如此找到的核是內固集,也是外固集,滿足核的定義,下面說明一下核為什么不是空集:實際上P[1]就不是空集,對一個沒有回路的有向圖來說,從圖上的某一點出發,就無法回到原來到過的點。而圖中的點又是有限的,所以最后必將在某個結點終止,故P不是空集。

 

針對不同的游戲,找核是一個麻煩事。首先生成圖,有向邊取決於游戲規則,然后當我們要找某個必敗態的時候,是要先找到之前所有的必敗態的,而這正是一個數學問題和一個編程問題的關鍵差別。在立方和分解問題[unsolved]中,我的問題的提法都是針對某一個特定輸入的n來看是否存在(x,y)滿足立方和或者平方和等於n.實際上,如果提法換成,輸出對所有不大於n的數中可以被分解的數,那么這種提法更適合計算機去解決,因為本質上來說,兩個問題是不一樣的。對於前者我只需要知道有關n的情況就可以了,而對后者,卻調動了資源去計算所有不大於n的數的情況。雖然他們看起來很相近,但是從道理上來說應該后者的勞動量要大得多,可悲的事情就在於,有時候你要算出n的情況,就不得不算一些比n小的數的情況,而這個計算的數目通常是隨着n增大而增大的;另一個可悲的事情是,程序員往往已經習慣了第二種提問方式。數學家希望找到某些必要條件或者充分條件來確定n能否被分解,同樣的道理,我們也希望能直接找到必敗態的規律,而不真正依賴於象上述定理那樣遞歸的思想從P[1]開始找起,這樣來解決問題。

 

但是,必敗態的規律是嚴格依賴於規則的,這一點對找出必敗態的規律來說造成了很大的局限性。這個圖的模型在以后還會遇到,到時有更好的方法來尋找必敗態。

 

 轉自http://yjq24.blogbus.com/logs/42304551.html

 

高斯取整函數又叫向下取整函數,常見的記法如下: ,既然是向下取整,也就是說[-3.5]=-4,這個取整對負數來說就不是簡單地扔掉小數部分,這是要注意的。可以說,高斯取整是聯系連續和離散的重要橋梁。

 

小知識:高斯函數性質

1) x-1<[x]<=x<[x]+1

2) [x+n]=[x]+n,(n為整數)

3) [x]+[y]<=[x+y]<=[x]+[y]+1 //左邊由性質2易證,右邊利用[x+y]<=x+y<[x]+[y]+2

4) [nx]>=n[x],(n為正整數) //反復利用性質3左邊

5) [x/n]=[[x]/n],(n為正整數)

// 換元后等價於證[ny]/n-1<[y]<=[ny]/n,右邊由性質4易證,左邊有 [ny]/n<=[y]+{y}<[y]+1

 

 

 

歐拉給出過一個很經典的多項式: ,該多項式在n=0,1,2,…,39時產生40個素數。利用高斯取整函數,可以做 一件差不多的事:

 

,這個函數跳過所有的平方數,而且值域覆蓋所有非完全平方數構成的集合,有了上面的這些性質作武器,證明並不難,這里就略去了。

 

今天的主題還是 Beatty定理

 

正無理數 滿足 , 則數列 嚴格遞增, 並且這兩個數列構成Z+上的一個分划(也就是它們無交地遍歷全體正整數)。

 

[題解]:

 

其實作為習題是不難的,顯然 ,於是 ,故

 

Step1.先證明兩數列不交:[反證]若 ,有 ,即有

 

兩式相加:得k<m+n<k+1,這和m,n,k都是自然數矛盾;

 

Step2.再證兩數列能取遍所有的正整數:[反證]若k不在 中,則有

 

於是

 

 

兩式分別除以 后相加:得 ,這和m,n,k都為自然數矛盾.

 

證畢.

 

由Beatty定理得到的兩個數列稱為互質數列,不過別被名稱所欺騙,a[n]和b[n]並不能保證對應互質。

//再繼續看看必敗點

一、
      m(k) = k * (1 + sqrt(5))/2
      n(k) = m(k) + k
 二、
 
一個必敗點有如下性質:
性質1:所有自然數都會出現在一個必敗點中,且僅會出現在一個必敗點中;
性質2:規則允許的任意操作可將必敗點移動到必勝點;
性質3:一定存在規則允許的某種操作可將必勝點移動到必敗點;
 
下面我們證明這3個性質。
 
性質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)的選擇原則,所有自然數都會出現在某個必敗點中。
 
 
性質2:規則允許的任意操作可將必敗點移動到必勝點;
證明:以必敗點(m(k),n(k))為例。若只改變兩個數中的一個,由於性質1,則得到的點一定是必勝點;若同時增加兩個數,由於不能改變兩數之差,又有n(k)-m(k)=k,故得到的點也一定是必勝點。
 
 
性質3:一定存在規則允許的某種操作可將必勝點移動到必敗點;
證明:以某個必勝點(i,j)為例,其中j>i。因為所有自然數都會出現在某個必敗點中,故要么i等於m(k),要么j等於n(k)。
若i=m(k),j>n(k),可從j中取走j-n(k)個石子到達必敗點;
若i=m(k),j<n(k),可從兩堆同時拿走m(k)-m(j-m(k)),注意此時j-m(k) < n(k)-m(k) < k,從而到達必敗點( m(j-m(k)),m(j-m(k))+j-m(k));
若i>m(k),j=n(k),可從i中取走i-m(k)個石子到達必敗點;
若i<m(k),j=n(k),需要再分兩種情況,因為i一定也出現在某個必敗點中,若i=m(l),則從j中拿走j-n(l),若i=n(l),則從j中拿走j-m(l),從而到達必敗點(m(l),n(l))。

 

//看完上面的有了點了解吧,代碼如下

#include<iostream>
#include<cmath>
using namespace std;
int main ()
{
    int a,b,dif;
    double p=(sqrt((double)5)+1)/double(2);
    while(cin>>a>>b)
    {
    dif=abs(a-b);//取差值
    a=a<b?a:b;//取較小的值
    if(a==(int)(p*dif))//判斷是不是奇異局勢
      printf("0\n");
    else printf("1\n");
    }
    return 0;
}

 

 該類問題另一種表述 

 移動的皇后

 

Problem Description
一個n * n棋盤上有一個皇后。每個人可以把它往左或下或左下45度移動任意多步。把皇后移動至左下角的游戲者獲勝。現在給出皇后初始的X坐標和Y坐標,如果輪到你先走,假設雙方都采取最好的策略,問最后你是勝者還是敗者。

  
Input
輸入包含若干行,表示若干種皇后的初始情況,其中每一行包含兩個非負整數a和b,表示皇后的初始坐標,a和b都不大於1,000,000,000。
Output
輸出對應也有若干行,每行包含一個數字1或0,如果最后你是勝者,則為1,反之,則為0。
Sample Input
2 1
8 4
4 7
Sample Output
0
1
0
 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM