Ferguson游戏——打表找规律

题意

有两个盒子分别有m颗糖果和n颗糖果,每次移动是将一个盒子清空而把另一个盒子里得一些糖果拿到被清空的盒子,使得两个盒子至少各有一个。无法移动者输。

分析

设初始状态为(m, n),显然(1, 1)是终态。

其实对于一个状态,只与两者之和有关。按k=m+n从小到大排序,就能递推的求出每个状态是必胜还是必败。

#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 100 + 10;
bool win[maxn][maxn];

void solve()
{
    win[1][1] = false;
    for(int k = 3;k < 20;k++)
    {
        for(int n = 1;n < k;n++)
        {
            int m = k - n;
            win[n][m] = false;
            for(int i = 1;i < n;i++)
                if(!win[i][n-i])  win[n][m] = true;
            for(int i = 1;i < m;i++)
                if(!win[i][m-i]) win[n][m] = true;
            //if(n <= m && win[n][m])  printf("%d %d\n", n, m);
        }
    }
}

int main()
{
    solve();
    for(int i = 1;i < 20;i++)
        for(int j = i;j <20;j++)
            if(win[i][j])  printf("%d %d\n", i, j);
}

发现规律:m,n都为奇数时先手必败;否则先手必胜。

参考链接:https://blog.csdn.net/TSY_1222/article/details/83277648

猜你喜欢

转载自www.cnblogs.com/lfri/p/11626212.html