Ildar Yalalov 博弈 判斷輸贏

2021-08-21 12:27:43 字數 1353 閱讀 1602

原題:gym - 101808i

題意:

有n堆石子,數量給出,每次操作可以將所有石子去掉1個,或者從一堆中去掉乙個,問就當前情況而言是必輸或贏

解析:

既然可以所有拿掉乙個,那麼可以看成柱形圖,所有柱子減一相當於去掉最下面一層

可以把所有情況,分為以下幾大類:(所以堆的最小數就是可以去掉的層數,上面的是拿掉所有層後剩下的數)

n的奇偶

把所有可以去掉的層去掉後,上面的奇偶

剩下層數的奇偶

操作的作用也有以下幾種:

不改變上面的奇偶,直接去一層

在最上層拿乙個,層數減一,上面的加上n-1個

拿上面的,上面的奇偶性反轉

對於第二個作用,如果n為奇數,上面的奇偶性不變;反之,反轉

先看n為偶的情況:

不管怎麼樣,都要從已知的最簡情況開始

0層,上面奇的情況:一直拿一定贏

0層,上面偶的情況:輸

1層,上面奇:進行2操作,給對面0層,上面偶必輸,贏

1層,上面偶:拿一層,給0層,上面偶必輸,贏

2層,上面偶或奇:進行12操作都是輸所以不能選,所以一直操作3,最後偶的情況不能操作3了,所以偶輸,奇贏

以後的情況就可以得出是迴圈了

結論:

n偶時,層數偶上面偶的情況輸,其他贏

n為奇的情況:

0層,上面奇的情況:一直拿一定贏

0層,上面偶的情況:輸

1層,上面偶:拿一層,贏

1層,上面奇:第二個操作不會改變上面的奇偶,只能轉到情況1或3,所以必輸

可以得出是迴圈了

結論:

n奇時,奇層上面奇 偶層上面偶必輸,其他贏

**:

int

main()

int ji=

0,cen=

10000000

;for

(int i=

1;i<=n;i++

)for

(int i=

1;i<=n;i++)if

(ji%2==

1)ji=1;

else ji=0;

if(n%2==

1)else

if(f)

printf

("yalalov\n");

else

printf

("shin\n");

}}

單鏈表判環判交問題

摘要 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?擴充套件 判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點。有乙個單鏈表,其中可能有乙個環,也就是某...

環形佇列如何判空和判滿

環形佇列的判空和判滿是乙個比較基礎的問題,可以通過以下兩種方法來實現,定義環形佇列抽象類 define max size 1024 class circularqueue circularqueue circularqueue int size this data new int size this...

博弈 巴什博弈

只有一堆n個物品,兩個人輪流從這堆物品中取物,規定每次至少取乙個,最多取m個。最後取光者得勝。顯然,如果n m 1,那麼由於一次最多只能取m個,所以,無論先取者拿走多少個,後取者都能夠一次拿走剩餘的物品,後者取勝。因此我們發現了如何取勝的法則 如果n m 1 r s,r為任意自然數,s m 那麼先取...