取石子遊戲

2022-07-19 18:57:08 字數 1396 閱讀 3449

有這樣一種取石子遊戲: 有若干堆石子,每堆石子的數量都是有限的,合法的操作是「選擇一堆石子並拿走若干顆(不能不拿)」;

現在有兩種判定勝負的方式:

1:  如果輪到某個人時所有的石子堆都已經被拿空了,則判負;

2: 如果輪到某個人時把所有的石子堆都拿空了, 使下乙個人沒石子可拿,則判負;

面對第一種判負規則時:  局面是必敗態當且僅當所有堆硬幣的數量都異或起來結果為0,即a1^a2^...^an=0; 下面是簡單說明.

首先:最終局面只有乙個,就是全0,異或仍然是0;

然後:對於某個局面(a1,a2,...,an),若a1^a2^...^an!=0(不等號就用c++的習慣用!=來表示了),一定存在某個合法的移動,將ai改變成ai'後滿足a1^a2^...^ai'^...^an=0。不妨設a1^a2^...^an=k,則一定存在某個ai,它的二進位制表示在k的最高位上是1(否則k的最高位那個1是怎麼得到的)。這時ai^k

最後:對於某個局面(a1,a2,...,an),若a1^a2^...^an=0,一定不存在某個合法的移動,將ai改變成ai'後滿足a1^a2^...^ai'^...^an=0。因為異或運算滿足消去率,由a1^a2^...^an=a1^a2^...^ai'^...^an可以得到ai=ai'。所以將ai改變成ai'不是乙個合法的移動;

面對第二種判負規則時 :

一種情況下是每堆都是1,那麼奇數時先手敗,

偶數時後手敗,

如果有一堆不都是1,那麼結果和前一種結果是一樣的; 

若只有一堆石子數大於1時,總可以對該堆石子操作,使操作後石子堆數為奇數且所有堆得石子數均為1  

若有超過一堆石子數大於1時,先手將最後的異或值變為0即可,這時總還存在某堆石子數大於1

hdu 1849

rabbit and grass

view code

1 #include 2

intmain( )314

if( !ans)

15 puts( "

grass win!");

16else

17 puts( "

rabbit win!");

18}19return0;

20 }

hdu 1907 john

view code

1 #include 2

3int

t, n, x;

4int

main( )515

if(ans)ans=1;16

if( f^ans )puts( "

brother");

17else puts("

john");

18}19return0;

20 }

取石子遊戲

如下 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 有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆...