POJ 2425 A Chess Game (博弈)

题意:一个有向无环图,制定M个点,每个点有一个石子。A,B两个玩家轮流移动这些石子(石子只能沿合法的边移动),最后没有石子可移的算输。

如果光看一个石子的话,这他妹的就是sg函数的定义啊。。。然后对整个图处理一下每个点的sg值。

对这M个点怎么处理,这么想吧。假设其中一个点为i,其sg值为sg[i] = a (a != 0)

那可以发现,i可以走向[0, a-1]的任意sg值,这相当与什么?相当与这里有一堆石子,共a个。。。。

M个点就是M堆石子,每堆石子的个数就是这个点的sg值。好吧Nim博弈出来了。。。

ps:有谁能把抑或傻逼的写成与,有谁能把标记数组写成全局变量???我能!脑子进屎了!

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%lld\n", x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout);

typedef long long LL;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int inf = 0x1F1F1F1F;

using namespace std;

const int N = 1024;

int n;
int sg[N];
vector<int> vc[N];

void dfs(int r) {
    if(sg[r] != -1) return ;
    if(vc[r].size() == 0) {
        sg[r] = 0; return ;
    }

    bool vis[N] = {false};

    for(int i = 0; i < int(vc[r].size()); ++i) {
        dfs(vc[r][i]);
        vis[sg[vc[r][i]]] = true;
    }
    for(int i = 0; i < n; ++i) {
        if(vis[i] == false) {sg[r] = i; break;}
    }
}

int main() {
    //Read();

    int i, t, a, ans;
    while(~scanf("%d", &n)) {
        for(i = 0; i < n; ++i) {
            scanf("%d", &t);
            vc[i].clear();
            while(t--) {
                scanf("%d", &a);
                vc[i].push_back(a);
            }
            sg[i] = -1;
        }
        for(i = 0; i < n; ++i) {
            if(sg[i] == -1) dfs(i);
        }
        while(scanf("%d", &t), t) {
            ans = 0;
            while(t--) {
                scanf("%d", &a);
                ans ^= sg[a];
               // printf("%d %d\n", a, sg[a]);
            }
            if(ans) puts("WIN");
            else    puts("LOSE");
        }
    }
    return 0;
}

 

posted @ 2013-04-28 16:03  AC_Von  阅读(1041)  评论(0编辑  收藏  举报