【Light OJ】No More Tic-tac-toe (博弈 SG函数)

题目链接:

http://acm.bnu.edu.cn/v3/problem_show.php?pid=13319


一道典型的求解SG函数的题目,校内组队赛中遇到此题。开题时有比较清晰的解题思路,但是因为不常刷题导致写代码效率低下,一道题的代码写了近3h。最终因为一个没发现的小错误导致没能AC。实力还是太弱,还是需要努力。

先说说我错误的原因。大家知道求SG函数时,我们只需要把那些直接与终止态相连的状态作为递归终点,手算出它们的SG值即可(一般很容易算),剩下的状态的SG函数直接递归求解即可。以此题为例,我用一个结构体p{l,r,len}来表示一个长度为len,左侧方块为l,右侧方块为r的状态,l,r有三种状态0,1,2,分别代表没放标记、放‘X’和放'O'。这样,我们只需要手算出长度为1的状态{0,0,1}、{0,1,1}、{0,2,1}...的答案, 其他状态直接搜索求解即可,但我画蛇添足地手算了len=2时各个状态的SG函数。然后....就算错了....(让我一个人静一静...

所以说不要做一些画蛇添足的事,求SG函数还是让它它自己去算吧。

接下来说一下算过SG函数之后得到的规律:l==r&&r==0时,SG=(len&1)?1:0;l==0||r==0时,SG=len;剩下的情况中,若l==r,则SG=1否则SG=0。


代码:


#define sc scanf
#define pr printf
#include
#include
#include
#include
#define LL long long
using namespace std;
const int N = 200;
const LL mod = 1000000007;
struct p {
    int l,r,len;
    bool operator < (const p& b)const {
        if(len==b.len&&l==b.l)
            return r mapp;

int dfs(p a) {
    if(mapp.count(a))
        return mapp[a];

    if(a.len == 0)
        return 0;
    else if(a.len==1) {
        if(a.l==0||a.r==0)
            return 1;
        else if(a.l==a.r)
            return 1;
        else
            return 0;
    } else {
        int ans = 0;
        bool vis[200];
        memset(vis,0,sizeof(vis));
        p p1,p2;
        p1.l = a.l;
        p1.r = 1;
        p2.l = 1;
        p2.r = a.r;
        for(int i=0; i


你可能感兴趣的:(博弈)