组合游戏略述——浅谈SG游戏的若干拓展及变形

Anti-SG 游戏
桌子上有 N 堆石子,游戏者轮流取石子。
每次只能从一堆中取出任意数目的石子,但不能不取。
取走最后一个石子者败。
 Anti-SG 游戏规定,决策集合为空的游戏者赢。
 Anti-SG 其他规则与 SG 游戏相同。
[结论](SJ 定理)
先手必胜当且仅当:( SG(i)=i )
(1)游戏的 SG 函数不为 0 且游戏中某个单一游戏的 SG 函数大于 1;
(2)游戏的 SG 函数为 0 且游戏中没有单一游戏的 SG 函数大于 1。

https://vjudge.net/problem/HDU-2509

#include 
using namespace std;
int main()
{
       int n,m;
   while(scanf("%d",&n)!=EOF)
   {
       int ans=0,flag=0;
       for(int i=0;i1) flag=1;//当所有数据都为1时的特判
       }
       if(flag){
        if(ans==0) puts("No");
        else puts("Yes");
       }
       else
       {
           if(n&1) puts("No");
           else puts("Yes");
       }
   }
}

Every-SG 游戏

待补充

翻硬币游戏
一般的翻硬币游戏的规则是这样的:
 N 枚硬币排成一排,有的正面朝上,有的反面朝上。我们从左开
始对硬币按 1 到 N 编号。
 游戏者根据某些约束翻硬币(如:每次只能翻一或两枚,或者每
次只能翻连续的几枚),但他所翻动的硬币中,最右边的必须是
从正面翻到反面。
 谁不能翻谁输。
有这样的结论:局面的 SG 值为局面中每个正面朝上的棋子单一存在
时的 SG 值的异或和。

#include
#include
#include
using namespace std;
//const int maxn=1010;
//int fx[maxn],g[maxn];
//void getSG()
//{
//    memset(fx,0,sizeof(fx));
//    for(int i=0;i<=100;i++)
//    {
//        memset(g,0,sizeof(g));
//
//        g[0]=1;//翻一个硬币,先手必赢
//
//        for(int j=0;j>=1;
    }
    return sum;
}
int main()
{
   int n,tmp,res;
   while(scanf("%d",&n)!=EOF)
   {
       set ss;
       res=0;
       for(int i=0;i

你可能感兴趣的:(组合游戏略述——浅谈SG游戏的若干拓展及变形)