您的位置:首页 > 其它

ZOJ 3666 Alice and Bob (SG博弈)

2014-08-26 22:04 471 查看
题目:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3666

题意:

给一个有向图,然后A和B轮流移动棋子,棋子在每一个位置可以重叠,当某人不能走时,输!

问A和B谁赢

方法:

显然每一局游戏都是独立的,对每一局游戏异或即可

每一局游戏的结果可以用SG求,记忆化搜索之

int dfs(int x)
{
if (sg[x] != -1) return sg[x];
bool vis[maxn];
memset(vis, 0, sizeof(vis));
for (int i = head[x]; ~i; i = edge[i].next)
vis[dfs(edge[i].v)] = 1;
for (int i = 0;; i++)
if (!vis[i]) return sg[x] = i;
}


代码:

/********************************************
*ACM Solutions
*
*@Title: ZOJ 3666 Alice and Bob
*@Version: 1.0
*@Time: 2014-08-26
*@Solution: http://www.cnblogs.com/xysmlx/p/xxxxxxx.html *
*@Author: xysmlx(Lingxiao Ma)
*@Blog: http://www.cnblogs.com/xysmlx *@EMail: xysmlx@163.com
*
*Copyright (C) 2011-2015 xysmlx(Lingxiao Ma)
********************************************/
// #pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <set>
#include <list>
#include <map>
#include <iterator>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long LL;
#define pb push_back
#define ROUND(x) round(x)
#define FLOOR(x) floor(x)
#define CEIL(x) ceil(x)
const int maxn = 10010;
const int maxm = 2000010;
const int inf = 0x3f3f3f3f;
const LL inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double INF = 1e30;
const double eps = 1e-6;
const int P[4] = {0, 0, -1, 1};
const int Q[4] = {1, -1, 0, 0};
const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1};
const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1};
struct Edge
{
int u, v;
int next;
Edge(int _u = 0, int _v = 0, int _next = 0): u(_u), v(_v), next(_next) {}
} edge[maxm];
int head[maxn];
int en;
void addse(int u, int v)
{
edge[en] = Edge(u, v, head[u]);
head[u] = en++;
}
int sg[maxn];
int n;
int kase;
void init()
{
kase++;
memset(head, -1, sizeof(head));
en = 0;
memset(sg, -1, sizeof(sg));
}
void input()
{
for (int i = 1; i < n; i++)
{
int w;
scanf("%d", &w);
while (w--)
{
int x;
scanf("%d", &x);
addse(i, x);
}
}
}
void debug()
{
//
}
int dfs(int x)
{
if (sg[x] != -1) return sg[x];
bool vis[maxn];
memset(vis, 0, sizeof(vis));
for (int i = head[x]; ~i; i = edge[i].next)
vis[dfs(edge[i].v)] = 1;
for (int i = 0;; i++)
if (!vis[i]) return sg[x] = i;
}
void solve()
{
printf("Case %d:\n", kase);
int ret = 0;
int q;
scanf("%d", &q);
while (q--)
{
int w;
ret = 0;
scanf("%d", &w);
while (w--)
{
int x;
scanf("%d", &x);
ret ^= dfs(x);
}
if (ret) puts("Alice");
else puts("Bob");
}
}
void output()
{
//
}
int main()
{
// int size = 256 << 20; // 256MB
// char *p = (char *)malloc(size) + size;
// __asm__("movl %0, %%esp\n" :: "r"(p));

// std::ios_base::sync_with_stdio(false);
#ifdef xysmlx
freopen("in.cpp", "r", stdin);
#endif

kase = 0;
while (~scanf("%d", &n))
{
init();
input();
solve();
output();
}
return 0;
}


ZOJ 3666
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: