poj 2425 A Chess Game grundy值

题意:

给一个拓扑图,在一些点上有棋子,两个玩家每次轮流将一颗棋子沿有向边移动一次,无法移动则失败。

分析:

理解nim和状态的grundy值两下就敲出来了。

代码:

//poj 2425
//sep9
#include <iostream>
#include <vector>
using namespace std;
const int maxN=1024;

vector<int> g[maxN];
int vis[maxN];
int grundy[maxN];

int dfs(int u)
{
	if(grundy[u]!=-1)
		return grundy[u];
	int val[1024];
	memset(val,0,sizeof(val));
	for(int i=g[u].size()-1;i>=0;--i)
		val[dfs(g[u][i])]=1;
	int i;
	for(i=0;;++i)
		if(val[i]==0)
			break;
	return grundy[u]=i;
}

int main()
{
	int n;
	while(scanf("%d",&n)==1){
		memset(vis,0,sizeof(vis));
		memset(grundy,-1,sizeof(grundy));
		for(int i=0;i<n;++i){
			g[i].clear();
			int num;
			scanf("%d",&num);
			while(num--){
				int x;
				scanf("%d",&x);
				g[i].push_back(x);
				vis[x]=1;
			}
		}
		for(int i=0;i<n;++i)
			if(vis[i]==0)
				dfs(i);
		int q;
		while(scanf("%d",&q)&&q){
			int ans=0;
			while(q--){
				int x;
				scanf("%d",&x);
				ans=ans^grundy[x];
			}
			if(ans) puts("WIN");
			else puts("LOSE");
		}
	}
	return 0;
}
时间: 2024-12-14 18:42:38

poj 2425 A Chess Game grundy值的相关文章

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 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 典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和.仍然是因为看不懂题目卡了好久. 这道题大概有两个坑, 1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了): 2.是n个点的有向无环图边数上限是n^2(re了好久QAQ). 在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快.下一篇大概会写一个小结. 代码 1 #include<cstdio> 2 #inclu

[原博客] POJ 2425 A Chess Game

题目链接题意:给定一个有向无环图(DAG),上面放有一些旗子,旗子可以重合,两个人轮流操作,每次可以把一个旗子从一个位置移动到相邻的位置,无法移动时输,询问先手是否必胜. 这道题可以把每个旗子看作单独的一个游戏,那么所有这些旗子的状态SG值,就是这些旗子各自SG值的Xor和,可以记忆化搜索dfs,暴力算SG值判断即可. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring&

poj 3537 Crosses and Crosses 博弈论之grundy值

题意: 给1*n的格子,轮流在上面叉叉,最先画得3个连续叉叉的赢,问先手必胜还是必败. 分析: 求状态的grundy值(也就是sg值),具体怎么求详见代码,为什么这么求要自己想的,只可意会(别人都说去看game theory,呵呵). 代码: //poj 3537 //sep9 #include <iostream> #include <set> using namespace std; int grundy[2048]; int h[2048]; int get_grundy(i

poj 2311 Cutting Game nim与状态的grundy值

题意: 给一个w*h的矩形,两人轮流只能沿格子的边缘横剪或竖剪,最先剪出1*1的格子的人获胜,问先手必胜还是必败. 分析: 此题要求对grundy值有理解.一个全局状态的grundy值是对游戏中某个状态的有效的描述,grundy值描述了当前状态的所有后继状态,比如n堆石子的nim游戏的grundy值是a1^a2^...an. 代码: //poj 2311 //sep9 #include <iostream> #include <set> using namespace std; c

博弈论:寻找先手必胜策略——Grundy值

选修了人工智能课程,老师布置了调研任务:Grundy,开始看了一些资料并没有看懂. 后来找到了一篇文,写的很棒,里面有好多博弈相关的问题与分析,分享出来给大家: http://endless.logdown.com/posts/2014/05/05/find-out-the-winning-strategies-of-the-game-nim-and-grundy-number-notes 这个服务器可能是外国的?打开的很慢,不要认为自己的网炸了...哈哈哈 下面就贴一点自己为了做海报(Grun

POJ Cutting Game(Nim博弈+grundy数)

Description Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes th

硬币游戏2&amp;&amp;Cutting Game——Grundy值

Grundy值 当前状态的Grundy值就是除任意一步所能转移到的状态的Grundy值以外的最小非负整数, 以硬币问题一为例,可写成: int init_grundy() { sg[0] = 0; for(int i = 1;i <= x;i++) //递推求前x个SG值 { set<int>st; for(int j = 0;j < k;j++) if(a[j] <= i) st.insert(sg[i - a[j]]); int g = 0; while(st.count