bzoj3609 [Heoi2014]人人盡說江南好
阿新 • • 發佈:2017-12-31
main end 數據 -- 最有 include 情況下 article lan
本題包括多組數據 數據第一行為一個數 T,為數據組數
以下 T 行,每行兩個正整數 n,m
7 3
1 5
4 3
6 1
2 2
1
1
1
0
Description
小 Z 是一個不折不扣的 ZRP(Zealot Round-game Player,回合制遊戲狂熱玩家),最近他 想起了小時候在江南玩過的一個遊戲。
在過去,人們是要邊玩遊戲邊填詞的,比如這首《菩薩蠻》就是當年韋莊在玩遊戲時填 的: 人 人 盡 說 江 南 好, 遊 人 只 合 江 南 老。 然而我們今天不太關心人們填的詞是什麽,我們只關心小 Z 那時玩過的遊戲。遊戲的規 則是這樣的,給定 N 堆石子,每堆石子一開始只有 1 個。小 Z 和他的小夥伴輪流操作, 小 Z 先行操作。操作可以將任意兩堆石子合並成為一堆,當誰不再能操作的時候,誰就輸掉了。 不過,當一堆石子堆的太高時可能發生危險,因此小 Z 和他的小夥伴規定,任何時刻任意一 堆石子的數量不能超過 m。即假如現在有兩堆石子分別有 a 個和 b 個,而且 a+b>m,那麽這 兩堆石子就不能合成一堆。 小 Z 和他的小夥伴都是很聰明的,所以他們總是會選擇對自己最有利的策略。現在小 Z 想要知道,在這種情況下,對於一個給定的 n 和 m,到底是誰能夠獲得勝利呢?Input
Output
輸出 T 行,每行為 0 或 1,如果為 0 意為小 Z(即先手)會取得勝利,為 1 則為後手會 取得勝利。
Sample Input
57 3
1 5
4 3
6 1
2 2
Sample Output
11
1
1
0
HINT
100%的數據, n,m<=1000000000, T<=100
正解:博弈論。
有一個結論,就是最後的序列一定是形如$m,m,m,...,n \ mod m$形式的,具體證明可以看這裏
因為我們知道開始和結束時的堆數,那麽就能算出總共要合並多少次,也就知道先手是否勝利了。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 6 using namespace std; 7 8 int n,m,tim; 9 10 il int gi(){ 11 RG int x=0,q=1; RG char ch=getchar(); 12 while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar(); 13 if (ch==‘-‘) q=-1,ch=getchar(); 14 while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); 15 return q*x; 16 } 17 18 il void work(){ 19 n=gi(),m=gi(),tim=(n-1)/m+1; 20 puts((n-tim)&1 ? "0" : "1"); return; 21 } 22 23 int main(){ 24 #ifndef ONLINE_JUDGE 25 freopen("game.in","r",stdin); 26 freopen("game.out","w",stdout); 27 #endif 28 RG int T=gi(); 29 while (T--) work(); 30 return 0; 31 }
bzoj3609 [Heoi2014]人人盡說江南好