1. 程式人生 > >bzoj3609 [Heoi2014]人人盡說江南好

bzoj3609 [Heoi2014]人人盡說江南好

main end 數據 -- 最有 include 情況下 article lan

Description

小 Z 是一個不折不扣的 ZRP(Zealot Round-game Player,回合制遊戲狂熱玩家),最近他 想起了小時候在江南玩過的一個遊戲。

在過去,人們是要邊玩遊戲邊填詞的,比如這首《菩薩蠻》就是當年韋莊在玩遊戲時填 的: 人 人 盡 說 江 南 好, 遊 人 只 合 江 南 老。 然而我們今天不太關心人們填的詞是什麽,我們只關心小 Z 那時玩過的遊戲。遊戲的規 則是這樣的,給定 N 堆石子,每堆石子一開始只有 1 個。小 Z 和他的小夥伴輪流操作, 小 Z 先行操作。操作可以將任意兩堆石子合並成為一堆,當誰不再能操作的時候,誰就輸掉了。 不過,當一堆石子堆的太高時可能發生危險,因此小 Z 和他的小夥伴規定,任何時刻任意一 堆石子的數量不能超過 m。即假如現在有兩堆石子分別有 a 個和 b 個,而且 a+b>m,那麽這 兩堆石子就不能合成一堆。 小 Z 和他的小夥伴都是很聰明的,所以他們總是會選擇對自己最有利的策略。現在小 Z 想要知道,在這種情況下,對於一個給定的 n 和 m,到底是誰能夠獲得勝利呢?

Input

本題包括多組數據 數據第一行為一個數 T,為數據組數 以下 T 行,每行兩個正整數 n,m

Output

輸出 T 行,每行為 0 或 1,如果為 0 意為小 Z(即先手)會取得勝利,為 1 則為後手會 取得勝利。

Sample Input

5
7 3
1 5
4 3
6 1
2 2

Sample Output

1
1
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]人人盡說江南好