https://www.luogu.org/problem/show?pid=1290
題目描述
歐幾里德的兩個后代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”
輸入輸出樣例
2 25 7 24 15
Stan wins Ollie wins
注意題目中說的,假設他們完美的操作。
什么是完美的操作呢?就是每個人都想讓自己贏。
題目中說的是減去正整數倍,那么減去的倍數不同,最終贏的人也不同。那么最終贏的人跟減去的倍數有沒有關系呢?
以樣例 25 7為例:
第一步Stan 有3種選擇,-7 -14 -21
① 若 減去1*7: 若減去2*7: 若減去3*7
Start:25 7 25 7 25 7
Stan:18 7 11 7 4 7
Ollie: 11 7 或 4 7 4 7 3 4
Stan: 4 7 或 3 4 3 4 1 3
Ollie: 4 3 或 1 3 1 3 1 0
Stan: 1 3 或 1 0 1 0 Ollie贏得了游戲的勝利。
Ollie: 1 0 或 Stan贏得了游戲的勝利。 Stan贏得了游戲的勝利。
Ollie贏得了游戲的勝利。
標紅色的地方表示選擇方法有大於等於2種
由此可見,當每次減的倍數大一倍時,贏得步驟會比上一次靠前一步,贏得人會跟上一個人不一樣。
同時可以深入推測,奇數倍和奇數倍的結果一樣,偶數倍和偶數倍的結果一樣。
所以我們可以推出,若到了某一步,這個人減數的方案有大於等於2種,那么在完美操作下就是這個人贏。因為它減奇數倍若輸,那么減偶數倍就能贏,反之也成立。也就是說他總能找到一種方,再給對方贏得機會前自己贏。
什么是贏得機會?
如果較大的數只能減去較小的數的一倍,那么這個人有且只有一種選擇方案,他不能左右自己贏還是輸。如果較大的數能減去較小的數大於等於2倍,由上面得出,他就可以先決定自己贏還是輸。注意是先決定。
所以本題的答案是:1、設m,n為輸入數據且m>n,第一個滿足條件m-n>n的步驟所對應的人為勝利者
2、m%n==0時的步驟所對應的人為勝利者。
#include<cstdio> #include<algorithm> using namespace std; int n,m,c,z,a; bool f; void dfs(int x,int y,int p) { if(f) return; if(x-y>y) { f=true;a=p; return; } if(x%y==0) { f=true;a=p; return; } dfs(y,x-y,(p+1)%2); } int main() { scanf("%d",&c); for(int i=1;i<=c;i++) { scanf("%d%d",&n,&m); f=false; dfs(max(n,m),min(n,m),1); if(a==1) printf("Stan wins\n"); else printf("Ollie wins\n"); } }
