小花梨的取石子遊戲 博弈

2021-09-23 01:38:54 字數 1435 閱讀 3514

小花梨有?堆石子,第?堆石子數量為??,?堆石子順時針編號為1 − ?(如圖)。

遊戲將進行?輪,每輪遊戲單獨進行,互不干擾,每輪初始時第?堆石子數目為??。

第?輪從編號為?的那堆石子為起點,順時針來取石子。兩人輪流取石子,不可不取,最少取 乙個石子,最多把當前這一堆取完,

只有取完一堆後才走到下一堆石子。走完一圈後石子都被取完,不能取石子的人就失敗。

假設兩人以最優策略進行取石子操作,請分別輸出 ? 輪遊戲是先手勝還是後手勝。

第一行為正整數?,表示石子的堆數 (1 ≤ ? ≤ 100000)

第二行輸入 ? 個正整數表示每一堆的石子數目?? (1 ≤ ?? ≤ 1e9 )

輸出 ? 行,第 ? 行表示第?輪遊戲的結果。

如果先手勝則輸出"?????",後手勝輸出"??????"。

2 1 3

first

second

first

2 2first

first

中文題,不解釋。注意是按順序。

剛開始想用的尼姆博弈,後來發現是按順序拿,不是任選一組。

多試幾組樣例會發現這樣幾個規律:

1)如果每輪第一堆不是1,那麼先手必勝。假設第一堆是a [ i ] 個,那麼先手可以通過拿a [ i ] - 1 個來獲得主動權。

2)如果序列全為1,則取決於堆數,奇數則先手必勝,偶數則先手必敗。這種情況需要單獨考慮,不然就會先手後手相繼輸出。

3)此外就需要計算每輪從第一堆開始連續1的個數,偶數則先手必勝,奇數則先手必敗。

其中,第(3)點找連續1的時候,如果是正常每次迴圈找的話會超時,所以就需要提前計算出來。

為了防止下標出錯,我把原序列連著存了兩遍,這樣只需要找 [ i , i+n-1 ] 區間就可以了。

如果直接用sum陣列從前往後遍歷的話,記錄的只能是開始到當前1的個數,所以倒著跑一遍,得到的才是正確答案。

#include #include #include #include #define mem(a,b) memset(a,b,sizeof(a))

#define fori(a,b) for(int i=a;i<=b;i++)

#define forj(a,b) for(int j=a;j<=b;j++)

using namespace std;

typedef long long ll;

int main()

for(int i=n*2; i>=1; i--)

fori(1, n)

else if(!flag)

else

}return 0;

}

博弈 小花梨的取石子遊戲

時間限制 1000ms 空間限制 512mb description 小花梨有 堆石子,第 堆石子數量為?堆石子順時針編號為 1 如圖 遊戲將進行?輪,每輪遊戲單獨進行,互不干擾,每輪初始時第?堆石子數目為?第?輪從編號為 的那堆石子為起點,順時針來取石子。兩人輪流取石子,不可不取,最少取 乙個石子...

問題 D 小花梨的取石子遊戲

本人是一名小弱雞,如果有錯誤,請各位大佬指出。第一次寫,希望大家能夠提出不足之處。小花梨有n堆石子,第i堆石子數量為ai,n堆石子順時針編號為1 n 如圖 遊戲將進行n輪,每輪遊戲單獨進行,互不干擾,每輪初始時第i堆石子數目為ai。第i輪從編號為i的那堆石子為起點,順時針來取石子。兩人輪流取石子,不...

ZOJ 問題 D 小花梨的取石子遊戲

題目描述 小花梨有n堆石子,第i堆石子數量為ai,n堆石子順時針編號為1 n 如圖 遊戲將進行n輪,每輪遊戲單獨進行,互不干擾,每輪初始時第i堆石子數目為ai。第i輪從編號為i的那堆石子為起點,順時針來取石子。兩人輪流取石子,不可不取,最少取乙個石子,最多把當前這一堆取完,只有取完一堆後才走到下一堆...