2011-0043

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

[http://en.wikipedia.org/wiki/Sprague-Grundy/ SG函数]的基本应用,Alice和Bob在一个有向图上移动,最后不能移动者便输了。
{{{
#include <set>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

typedef vector<int> VI;
typedef set<int> SI;

const int MAXN = 10086;

int n;
int sg[MAXN];
VI f[MAXN];

int calc_sg(int x) {
    int i, j, k;
    SI mex;
    mex.clear();

    if (sg[x] >= 0) return sg[x];
    if (x == n) return sg[x] = 0;
    for (i=0; i<f[x].size(); ++i) {
        mex.insert(calc_sg(f[x][i]));
    }
    for (i=0; ; ++i) if (mex.find(i) == mex.end()) return sg[x] = i;
}

int main() {
    int i, j, k;
    int m;
    int x, y;
    int q;
    int tot;
    int cn(0);

    while (1 == scanf("%d", &n)) {
        for (i=1; i<=n; ++i) f[i].clear();
        for (i=1; i<n; ++i) {
            scanf("%d", &m);
            for (j=0; j<m; ++j) {
                scanf("%d", &x);
                f[i].push_back(x);
            }
        }
        memset(sg, -1, sizeof(sg));
        for (i=1; i<=n; ++i) sg[i] = calc_sg(i);
        //for (i=1; i<=n; ++i) printf("%d ", sg[i]); puts("");
        printf("Case %d:\n", ++cn);
        scanf("%d", &q);
        while (q--) {
            scanf("%d", &m);
            scanf("%d", &x);
            x = sg[x];
            for (i=1; i<m; ++i) {
                scanf("%d", &y);
                x ^= sg[y];
            }
            if (x == 0) puts("Bob");
            else puts("Alice");
        }
    }

    return 0;
}
}}}

[by delta_4d]

SG函数的基本应用,Alice和Bob在一个有向图上移动,最后不能移动者便输了。

#include <set>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
typedef vector<int> VI;
typedef set<int> SI;
const int MAXN = 10086;
int n;
int sg[MAXN];
VI f[MAXN];
int calc_sg(int x) {
    int i, j, k;
    SI mex;
    mex.clear();
    if (sg[x] >= 0) return sg[x];
    if (x == n) return sg[x] = 0;
    for (i=0; i<f[x].size(); ++i) {
        mex.insert(calc_sg(f[x][i]));
    }
    for (i=0; ; ++i) if (mex.find(i) == mex.end()) return sg[x] = i;
}
int main() {
    int i, j, k;
    int m;
    int x, y;
    int q;
    int tot;
    int cn(0);
    while (1 == scanf("%d", &n)) {
        for (i=1; i<=n; ++i) f[i].clear();
        for (i=1; i<n; ++i) {
            scanf("%d", &m);
            for (j=0; j<m; ++j) {
                scanf("%d", &x);
                f[i].push_back(x);
            }
        }
        memset(sg, -1, sizeof(sg));
        for (i=1; i<=n; ++i) sg[i] = calc_sg(i);
        //for (i=1; i<=n; ++i) printf("%d ", sg[i]); puts("");
        printf("Case %d:\n", ++cn);
        scanf("%d", &q);
        while (q--) {
            scanf("%d", &m);
            scanf("%d", &x);
            x = sg[x];
            for (i=1; i<m; ++i) {
                scanf("%d", &y);
                x ^= sg[y];
            }
            if (x == 0) puts("Bob");
            else puts("Alice");
        }
    }
    return 0;
}

[by delta_4d]