題目描述
歐幾里德的兩個後代Stan和Ollie正在玩一種數字遊戲,這個遊戲是他們的祖先歐幾里德發明的。給定兩個正整數M和N,從Stan開始,從其中較大的一個數,減去較小的數的正整數倍,當然,得到的數不能小於0。然後是Ollie,對剛才得到的數,和M,N中較小的那個數,再進行同樣的操作……直到一個人得到了0,他就取得了勝利。下面是他們用(25,7)兩個數遊戲的過程:
Start:25 7
Stan:11 7
Ollie:4 7
Stan:4 3
Ollie:1 3
Stan:1 0
Stan贏得了遊戲的勝利。
現在,假設他們完美地操作,誰會取得勝利呢?
輸入輸出格式
輸入格式:
第一行為測試資料的組數C。下面有C行,每行為一組資料,包含兩個正整數M, N。(M, N不超過長整型。)
輸出格式:
對每組輸入資料輸出一行,如果Stan勝利,則輸出“Stan wins”;否則輸出“Ollie wins”
輸入輸出樣例
輸入樣例#1:
2 25 7 24 15
輸出樣例#1:
Stan wins Ollie wins
設先手勝利與否為d(a,b),不妨設a>=b。
由“一個狀態必勝當且僅當它的有至少一個後繼狀態必敗”可以列出:
當a-b>b時,d(a,b)=(not d(a-b,b)) or (not d(a-2b,b)) or ... or (not d(a mod b,b)),
此時又有d(a-b,b)=(not d(a-2b,b)) or (not d(a-3b,b)) or ... or (not d(a mod b,b)),
代入得到d(a,b)=(not d(a-b,b)) or d(a-b,b)=true。
當a-b=b時,顯然d(a,b)=true。
當a-b<b時,若a>b,有且只有一種決策,即d(a,b)=not d(b,a-b),若a=b,有d(a,b)=true。
將遞迴改為迴圈(實際意義為模擬每一局的策略)即可(資料水,也可以不改)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 const int MAXN=5001; 9 void read(int &n) 10 { 11 char c='+';int x=0;bool flag=0; 12 while(c<'0'||c>'9') 13 {c=getchar();if(c=='-')flag=1;} 14 while(c>='0'&&c<='9') 15 {x=x*10+c-48;c=getchar();} 16 flag==1?n=-x:n=x; 17 } 18 int main() 19 { 20 int T; 21 read(T); 22 while(T--) 23 { 24 int x,y; 25 read(x);read(y); 26 int now=1; 27 if(x<y)swap(x,y); 28 while(1) 29 { 30 if(x==y||x-y>=y) 31 break; 32 now=!now; 33 int tmp=x-y; 34 x=y; 35 y=tmp; 36 } 37 if(now) 38 printf("Stan wins\n"); 39 else 40 printf("Ollie wins\n"); 41 } 42 43 return 0; 44 }