您的位置:首页 > 其它

HDOJ 1536 S-Nim

2011-08-07 18:30 260 查看
首先,S-Nim是经典的博弈类的题目可以用Sprague-Grundy函数进行解决,关于Sprague-Grundy函数的方法,见链接文章:Sprague-Grundy函数

其次,关于Sprague-Grundy函数的SG值。S-Nim类的游戏转化为Nim游戏,并将每个点当做一堆石子,该点的SG值当做该堆的石子数。但是为什么SG值有什么意义?为什么可以转化为石子数?只有理解了SG值的确切意义才能完全明白为什么S-Nim向Nim的转化。看一下以下例子:

SG=g(x)={0,1,2,3}=4 ............................................. ①

SG=g(x)={0,1,2,3,5}=4 ..............................................②

SG=g(x)={1,2,3,5}=0 .................................................③

对比①和②可以发现,SG值似乎丢失了一些信息,②中的5值并没有通过SG值表示出来。对比②和③可以发现,③中信息似乎完全丢失了。但,是不是真的如此呢?回到博弈类题目的出发点:

一、博弈题目依据什么推测最终的输赢?

答:依据的是当前点处于必胜点,还是必败点。除此之外无需假借任何条件。

二、必胜点与必败点有什么性质。

答:(1) 所有终结点是必败点(P点);

(2) 从任何必胜点(N点)操作,至少有一种方法可以进入必败点(P点);

(3)无论如何操作, 从必败点(P点)都只能进入必胜点(N点).

然后,看一下SG值,SG值为零的点,则为P点(即,必败点),否则为N点(即,必胜点)。以上SG值的性质满足必败点与必胜点的所有性质:(1)所有终结点的SG值为零,为必败点。(2)若SG值不为零,则其为必胜点。设其值为m,则有SG=g(x)={0,1,2,....m-1}=m,大括号中的0为其后继点的SG值,即该点为必败点。所以满足从必胜点至少有一种方法进入必败点。(3)若,SG值为零的点不是终结点,则必存在一个值为m的点,使得SG=g(x)={...,m,...},大括号中的m为其后继点的SG值,即该点为必胜点。所以满足从必败点都只能进入必胜点。

综上所诉,SG值为零的点,则为P点(即,必败点),否则为N点(即,必胜点)。满足必胜点与必败点所有的性质。并且可以作为推测输赢的依据。例②中所谓的信息丢失并不存在,因为SG值仅仅关注零和非零,其重点在于后继点的SG值中是否存在零。例③中的信息同样并未丢失,因为其SG值为零恰恰表明了后继点中有不为零的值存在(或无后继点),而必败点仅仅关心这一点信息。所以SG值仅有两个意义,零和非零,标明了该点为必胜点还是必败点。因为石子的数量与SG值起到的相同的作用(标明必胜点或者必败点),因此S-Nim类题目转化为Nim类题目时可以将SG值与石子数量同等对待,更是因为如此S-Nim题目才可以转化为Nim类题目。

有了以上转换S-Nim就不难搞定了,代码贴上来:

View Code

//#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
int f[10001];
unsigned set[101];
int setNum;

int mex(int v)
{
bool g[101]={0};
for (int i=0;i<setNum;i++)
{
int t=v-set[i];
if(t<0)
break;
if(f[t]==-1)
f[t]=mex(t);
g[f[t]]=1;
}
for (int i=0;i<101;i++)
{
if(!g[i])
return i;
}
}
int main()
{
//ifstream cin("S-Nim.txt");
while(cin>>setNum,setNum)
{
for(int i=0;i<setNum;i++)
cin>>set[i];
sort(set,set+setNum);
memset(f,-1,sizeof(f));
f[0]=0;
int caseNum;
cin>>caseNum;
while(caseNum--)
{
int num;
cin>>num;
int s=0,value;
while(num--)
{
cin>>value;
if(f[value]==-1)
f[value]=mex(value);
s=s^f[value];
}
if(s==0)
cout<<"L";
else
cout<<"W";
}
cout<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: