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;
}
posted @ 2024-06-25 15:18  blind5883  阅读(1)  评论(0编辑  收藏  举报