题目链接:这里
题意:给两个整数a和b,两个人先后用较大的数减去较小数的整数倍,并且保证相减后不为负数。先把一个数变为0的人获胜。
解法:真心觉得博弈难,可能是自己找必胜状态找得不好,感觉是需要一些智商来刚博弈的。下面的分析来自这位同学
很显然,当大数是小数的整数倍时为必胜态。
从这道题学会一个叫做自由度的东西,感觉能够为博弈推理提供思路。
博弈基本就是一个推理必胜态和必败态的过程。自由度越低越好推理。
不妨假设b为两个数中的较大数。
如果b-a小于a
那么只能选择用b去减a,如果后继态是必胜态,那么该状态是必败态,否则就是必胜态。
如果b-a大于a呢?
我们怎么能够转移到自由度较低的情况。
假设x是是的b-x*a小于a的整数。
那么我们用b减去(x-1)*a。这个就变成了第一种情况,如果第一种情况是必败态,那么此时就是必胜态。
如果减去(x-1)*a是必胜态呢?那么b-a*x是不是就变成了必败态?(有点绕,仔细想想),所以当前状态还是必胜态。
所以就是比谁先达到自由度高的情况即可。

主要是分析,除了求sg函数的博弈,一般博弈的代码一般就几排,思维最重要啊。

//POJ 2328

#include <stdio.h>
#include <algorithm>

int main()
{
    int a, b;
    while(scanf("%d%d", &a,&b) != EOF)
    {
        if(a == 0 && b == 0) break;
        bool flag = 1;//
        while(1){
            if(a > b) std::swap(a, b);
            if(b%a == 0) break;
            if(b-a>a) break;
            b -= a;
            flag ^= 1;
        }
        if(flag) puts("Stan wins");
        else puts("Ollie wins");
    }
    return 0;
}