P1290 欧几里德的游戏
P1290 欧几里德的游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
先按正常欧几里得算法来一遍,就能发现一些规律。如开始的 \((25,7)\),我们把交替辗转前后算作两个阶段,那么 \((25,7)\) 的阶段如下:
\((25, 7) \to (4, 7) \to (4, 3) \to (1, 3) \to (1, 0)\) ,他们对应可以减去的正整数倍数依次为 \(3, 1, 1, 3\),(出现 0 不算),你会发现,如果一个阶段我没减尽,就不会到下一个阶段,而每一个阶段我都可以减任意不超过的正整数倍数。这就有一点 Nim 游戏的感觉了。
如果倍数是 \(1\),那么只能取完。而如果不是 \(1\),我就可以操控让这个阶段剩下一个 \(1\),或者直接取完。因为倍数都是 \(1\) 的一系列阶段只能依次取,而先到达倍数非 \(1\) 阶段的人,可以保证自己一定可以到达下一个非 \(1\) 阶段,或者到达 \(0\) 获胜。也就是说,先到达非 \(1\) 阶段的人是必胜态。因此,本题利用辗转相除法判断谁先到非 \(1\) 阶段即可。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m;
bool gcd(int x, int a, int b)
{
if (b != 0)
{
if (a / b != 1) return x & 1;
}
else return !(x & 1);
return gcd(x + 1, b, a % b);
}
int main()
{
int T;
cin >> T;
while (T -- )
{
cin >> n >> m;
if (n < m) swap(n, m);
if (gcd(1, n, m)) puts("Stan wins");
else puts("Ollie wins");
}
return 0;
}