欧几里德的两个后代 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<2^31)。
输出格式
对每组输入数据输出一行,如果 Stan 胜利,则输出 Stan wins;否则输出 Ollie wins。
输入 :
2
25 7
24 15
输出:
Stan wins
Ollie wins
这是博弈论和欧几里得算法的结合,这道题我刚开始自己没有想出思路,感觉这种类型的题目第一次做,所以记在这里。
对于当前的两个数m,n(假设m始终为大数),如果m是n的倍数,那么当前的这个人肯定是可以得到0,也就是他稳赢。
如果m=K*n+z,(k>=2)那么当前的人可以得到(n+z,n)和(n,z)这两种情况,因为是两个人之间的互相博弈,所以这个人可以自己决定得到哪种情况,那么必赢的情况肯定是这两者之一,所以此时当前人也是稳赢。
如果k=1,那么当前的这个人只能得到(n,z)这种情况,此时就要拿n,z再去递归去看后面的胜负所定了。
AC代码附上:
#include <iostream>
using namespace std;
int gmd(int m, int n,int flag)
{
if (m % n == 0)
return flag;
if (m / n >= 2)
return flag;
else
{
return gmd(n, m - n,++flag);
}
}
int main()
{
int t;
cin >> t;
int m, n,k,flag;
while (t--)
{
cin >> m >> n;
flag=1;
if (m < n)
{
int temp;
temp = m;
m = n;
n = temp;
}
k = gmd(m, n,flag);
if (k % 2 == 1)
cout << "Stan wins" << endl;
else
cout << "Ollie wins" << endl;
}
}