GG and MM(every sg 游戏)

    科技2022-07-14  127

    GG and MM

    结论

    题意:

    每组给n个游戏,每个游戏有两堆石头,GG和MM轮流操作,操作规则:

    从两堆里面选出一堆,假设这堆石头有x个,然后在另一堆里取k*x个石头(k是正整数)

    谁不能取石头谁输,MM先手。

    思路:

    这是一个every——sg游戏。

    决定总游戏胜负的是最后一局游戏的胜负。因为不能取石头的情况就已经是最后一局了,所以之前的游戏胜负情况没有意义。

    那么为了自己能赢,对于自己会赢的游戏,我肯定想尽可能地延长时间,对于自己会输的游戏,我肯定想尽可能地结束。

    那么可以找出每一局所走的时间,最后进行判断即可。

    代码

    /* Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> #define mp make_pair #define pb push_back #define endl '\n' #define mid (l + r >> 1) #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define ls rt << 1 #define rs rt << 1 | 1 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double pi = acos(-1.0); const double eps = 1e-7; const int inf = 0x3f3f3f3f; inline ll read() { ll f = 1, x = 0; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f * x; } const int N = 1e3 + 10; int a[N], b[N], sg[N][N], step[N][N]; int get_sg(int x, int y) { if(x > y) swap(x, y); if(sg[x][y] != -1) return sg[x][y]; if(!x || !y) return sg[x][y] = step[x][y] = 0; int tempx = y % x, tempy = x; int k = y / x; if(k == 1) { sg[x][y] = get_sg(tempx, tempy) ^ 1; step[x][y] = step[tempx][tempy] + 1; return sg[x][y]; } else { step[x][y] = get_sg(tempx, tempy) + step[tempx][tempy] + 1; return sg[x][y] = 1; } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); memset(sg, -1, sizeof sg); int n; while(scanf("%d", &n) != EOF) { int maxn = 0; for(int i = 1; i <= n; i++) { int x, y; scanf("%d %d", &x, &y); if(x > y) swap(x, y); get_sg(x, y); maxn = max(maxn, step[x][y]); } puts(maxn & 1 ? "MM" : "GG"); } return 0; }
    Processed: 0.009, SQL: 8