洛谷 1290 歐幾里德的游戲


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”

輸入輸出樣例

輸入樣例#1:
2
25 7
24 15
輸出樣例#1:
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");
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM