YBTOJ魔法珠(博弈论)
这道题是NIM游戏和有向图游戏结合的博弈论问题。题面咋一看这就是个NIM游戏,怎么把它转到有向图游戏呢?我们假设NIM游戏中一个大的局面为一个根节点,然后所有小的子局面为叶节点,这样,NIM游戏就转化为了有向图游戏。最后我们根据NIM相关定理可得:SG(1)SG(2)……^SG(n)=0则先手必败,反之先手必胜。求SG函数部分具体看代码注释。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,x,sg[1010],ans;
inline int SG(int x)
{
if(sg[x]!=-1)return sg[x];
int y=0;
for(int i=1;i*i<=x;++i) if(!(x%i)) {if(i!=x) y^=SG(i); if(i*i!=x&&i!=1) y^=SG(x/i);}//先求出所有子局面异或和
bool ch[1010]; memset(ch,0,sizeof(ch));
for(int i=1;i*i<=x;++i) if(!(x%i)) {if(i!=x) ch[SG(i)^y]=1; if(i*i!=x&&i!=1) ch[SG(x/i)^y]=1;}//枚举每一种子局面,y^SG(i)即表示消去第i堆
while(ch[++sg[x]]);//统计答案
return sg[x];
}
int main()
{
for(int i=1;i<=1000;++i)sg[i]=-1;
while(scanf("%d",&n)!=EOF)
{
ans=0;
while(n--) scanf("%d",&x),ans^=SG(x);
printf(ans?("freda\n"):("rainbow\n"));
}
return 0;
}