遊戲將進行?輪,每輪遊戲單獨進行,互不干擾,每輪初始時第?堆石子數目為??。
第?輪從編號為?的那堆石子為起點,順時針來取石子。兩人輪流取石子,不可不取,最少取 乙個石子,最多把當前這一堆取完,
只有取完一堆後才走到下一堆石子。走完一圈後石子都被取完,不能取石子的人就失敗。
假設兩人以最優策略進行取石子操作,請分別輸出 ? 輪遊戲是先手勝還是後手勝。
第一行為正整數?,表示石子的堆數 (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的那堆石子為起點,順時針來取石子。兩人輪流取石子,不可不取,最少取乙個石子,最多把當前這一堆取完,只有取完一堆後才走到下一堆...