(博弈/SG)欧几里得的游戏

https://www.luogu.org/problemnew/show/P1290
给出n, m,每个人可以用大的数减去任意倍的小的数(大的数被减后>=0),两人轮流操作,遇到一个数为0时即输

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

bool solve(int n, int m) {
    if(!m) return false;
    if(n / m == 1) return !solve(m, n % m);
    else return true;
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--) {
        int m, n;
        scanf("%d%d", &m, &n);
        if(m < n) swap(m, n);
        if(solve(m, n))
            printf("Stan wins\n");
        else
            printf("Ollie wins\n");
    }
}

::n>m
sg(n,m) = mem{sg(n - m, m), sg(n - 2m, m), sg(n - 3m, m), … , sg(m, n % m)};
sg(n - m, m) = mem{sg(n - 2m, m), sg(n - 3m, m), … , sg(m, n % m)}
sg(n - 2m, m) = mem{sg(n - 3m, m), … , sg(m, n % m)}
->除了sg(m, n % m)的项都可以由sg(m, n % m)求出
设sg(m, n % m) = 0, n / m = k, 则sg(n - (k - 1) * m, m) = mem{sg(m, n % m)} = 1
后面的sg就为2, 3, 4, …即为必胜
设sg(m, n % m) = 1, n / m = k, 则sg(n - (k - 1) * m, m) = mem{sg(m, n % m)} = 0
后面的sg也为2, 3, 4, 必胜
可知若n / m == 1, k = 1, sg(n, m) = !sg(m, n % m)

猜你喜欢

转载自blog.csdn.net/weixin_40588429/article/details/83864273