POJ 2425 A Chess Game 博弈论 sg函数

http://poj.org/problem?id=2425

典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和。仍然是因为看不懂题目卡了好久。

这道题大概有两个坑,

1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了);

2.是n个点的有向无环图边数上限是n^2(re了好久QAQ)。

在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快。下一篇大概会写一个小结。

代码

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<map>
 7 using namespace std;
 8 const int maxn=1010;
 9 int n,m;
10 struct nod{
11     int y,next;
12 }e[maxn*maxn];
13 int head[maxn]={},tot=0;
14 int f[maxn]={};
15 void dfs(int x){
16     if(f[x]!=-1)return;
17     if(head[x]==0){
18         f[x]=0;return;
19     }
20     bool vis[maxn]={};
21     for(int i=head[x];i;i=e[i].next){
22         dfs(e[i].y);
23         vis[f[e[i].y]]=1;
24     }
25     for(int i=0;i<=n;i++){
26         if(!vis[i]){
27             f[x]=i;break;
28         }
29     }
30 }
31 int main(){
32     while(~scanf("%d",&n)){
33         int x,y;
34         memset(head,0,sizeof(head));
35         memset(f,-1,sizeof(f));
36         tot=0;
37         for(int i=1;i<=n;i++){
38             scanf("%d",&x);
39             for(int j=1;j<=x;j++){
40                 scanf("%d",&y);
41                 e[++tot].y=y+1;
42                 e[tot].next=head[i];
43                 head[i]=tot;
44             }
45         }
46         for(int i=1;i<=n;i++){
47             if(f[i]==-1)dfs(i);
48         }
49         while(~scanf("%d",&m)){
50             if(m==0)break;
51             y=0;
52             for(int i=1;i<=m;i++){
53                 scanf("%d",&x);
54                 y^=f[x+1];
55             }
56             if(y){
57                 printf("WIN\n");
58             }
59             else{
60                 printf("LOSE\n");
61             }
62         }
63     }
64     return 0;
65 }

时间: 2024-10-13 02:46:58

POJ 2425 A Chess Game 博弈论 sg函数的相关文章

poj 2425 A Chess Game(SG函数)

A Chess Game Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3551   Accepted: 1440 Description Let's design a new chess game. There are N positions to hold M chesses in this game. Multiple chesses can be located in the same position. The

POJ 2425 A Chess Game#树形SG

http://poj.org/problem?id=2425 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node { int to,next; }e[10000010]; int head[1010],Ecou; int sg[1010]; void add_edge(int u,int v) {

poj 1079 Calendar Game(博弈论 SG)

Calendar Game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2519    Accepted Submission(s): 1438 Problem Description Adam and Eve enter this year's ACM International Collegiate Programming Co

POJ 2960 S-Nim 博弈论 sg函数

http://poj.org/problem?id=2960 sg函数几乎是模板题. 调试代码的最大障碍仍然是手残在循环里打错变量名,是时候换个hydra产的机械臂了[超想要.jpg] 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<iostream> 6 #include<map> 7 using na

2016多校联合训练1 B题Chess (博弈论 SG函数)

题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外,不能移动了就算输,两个人都用最优策略,问先手是否有必胜策略. 这题显然就是SG函数了吧.行与行之间互不影响,所以可以看成n个子游戏,求出它们各自的SG函数然后异或一下就可以了.我们发现只有20列,2^21=2097152,所以我们可以先把行的所有情况的SG函数预处理出来,然后每次询问O(1)就行了. 代

HDU 1524 - A Chess Game(sg函数 + dfs)

A Chess Game Problem Description Let's design a new chess game. There are N positions to hold M chesses in this game. Multiple chesses can be located in the same position. The positions are constituted as a topological graph, i.e. there are directed

[BZOJ 1874] [BeiJing2009 WinterCamp] 取石子游戏 【博弈论 | SG函数】

题目链接:BZOJ - 1874 题目分析 这个是一种组合游戏,是许多单个SG游戏的和. 就是指,总的游戏由许多单个SG游戏组合而成,每个SG游戏(也就是每一堆石子)之间互不干扰,每次从所有的单个游戏中选一个进行决策,如果所有单个游戏都无法决策,游戏失败. 有一个结论,SG(A + B + C ... ) = SG(A)^SG(B)^SG(C) ... 这道题每堆石子不超过 1000 , 所以可以把 [0, 1000] 的 SG 值暴力求出来,使用最原始的 SG 函数的定义, SG(u) = m

博弈论SG函数

SG(x)=mex(S),S是x的后继状态的SG函数集合,mex(S)表示不在S内的最小非负整数.如果为0就是必败状态,否则就是必胜状态. 这道题目和Nim差不多,一共有两群熊猫,依次分析,最后异或即可. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue&g

博弈论-sg函数

今天A了张子苏大神的sg函数的题,感觉神清气爽. 一篇对于sg函数讲的很透彻的博文:http://acm.hdu.edu.cn/forum/read.php?fid=9&tid=10617 我来整理一下: 问题1:今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若干根, 可将一堆全取走,但不可不取,最后取完者为胜,求必胜的方法.  定义:若所有火柴数异或为0,则该状态被称为利他态,用字母T表示:否则, 为利己态,用S表示. 注意:这篇博文是先定义s和t,再通过它们的性质推出结论. [定理