P1290 歐幾里德的遊戲

自為風月馬前卒發表於2017-07-09

題目描述

歐幾里德的兩個後代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 }

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 

相關文章