前面几天补了SG函数的知识点就来写一篇题解。
因为两堆石子可以看作两个单独的ICG(公平组合游戏)游戏,这个游戏规则对两个人公平于是我们可以使用sg函数。
我们定义一个函数,对于公平组合游戏来说
,这个公式意味着从
的状态转移到
状态,也就是找到
可转移集合中没有出现的最小非负整数。其中
。我们一般把
称为必输态。
对于由很多个ICG组合成的一个复杂游戏,我们有Sprague–Grundy 定理
定义若干个的组合构成的一个游戏:两个玩家轮流对这个游戏中的任意
进行操作一次,当所有的子游戏无法操作时,游戏结束。计两个
游戏的状态分别为
,则这两个
游戏和状态就是
。对于
函数有:
其中 代表异或操作。
我们可以将 定理推广值多元有:
这样我们就可以将单一游戏的情况推广到全局游戏。若最终时,就可以判断谁必败,谁必胜。
在本题中
预处理前100的sg值。 最后判断sg(n+m)==0即可。
int pd[105];
int num[]={1,3,9};
void solve(){
for(int i=1;i<=100;i++){
int sg=0;
//vector<int> seek;
int used[5]={0};
for(int j=0;j<3;j++){
if(i-num[j]>=0){
used[pd[i-num[j]]]=1;
}
}
while(sg<5&&used[sg])++sg;
pd[i]=sg;
}
while(cin>>n>>m){
int ans=0;
ans^=pd[n];
ans^=pd[m];
if(ans) cout<<"win"<<endl;
else cout<<"lose"<<endl;
}
}

京公网安备 11010502036488号