巴什博弈(取石子)//最后取,胜
if (n % (p + q) == 0)//p为最少取,q为最多取
{
printf("second\n"); //必败态
}
else
{
printf("first\n"); //必胜态
}
巴什博弈(取石子)//最后取,败
while (scanf("%lld%lld%lld", &n, &p, &q) != EOF) //n总数,p最小,q最大
{
m = n % (p + q);
if (m == 0)
m = p + q;
if (m <= p)
{
printf("LOST\n");
}
else
{
printf("WIN\n");
}
}
Fibonacci博弈
f[1] = f[2] = 1;
for (ll i = 3; i <= 46; i++)//int范围
{
f[i] = f[i - 1] + f[i - 2];
}
while (scanf("%lld", &n) != EOF, n)
{
flag = 0;
for (ll i = 3; i <= 46; i++)
{
if (n == f[i])
{
flag = 1;
break;
}
}
if (flag)
{
printf("Second win\n");//必败态
}
else
{
printf("First win\n");//必胜态
}
}
SG打表
bool sg[maxn][maxn];
inline void getSg(int x, int y)
{
for (int upx = 1;; upx++)
{
if (upx + x > 5000 && upx + y > 5000)
return;
for (int upy = 0;; upy++)
{
int up = upx * upy;
if (up + y > 5000 && up + x > 5000)
break;
if (up + y <= 5000 && upx + x <= 5000)
{
sg[x + upx][y + up] = 1;
sg[y + up][x + upx] = 1;
}
if (y + upx <= 5000 && x + up <= 5000)
{
sg[y + upx][x + up] = 1;
sg[x + up][y + upx] = 1;
}
}
}
}
for (int i = 0; i <= 5000; i++)
{
for (int j = 0; j <= i; j++)
{
if (!sg[i][j])
getSg(i,j);
}
}
DFS打表
//注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍
//n是集合s的大小 S[i]是定义的特殊取法规则的数组
int s[110],sg[10010],n;
int SG_dfs(int x)
{
int i;
if(sg[x]!=-1)
return sg[x];
bool vis[110];
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
{
if(x>=s[i])
{
SG_dfs(x-s[i]);
vis[sg[x-s[i]]]=1;
}
}
int e;
for(i=0;;i++)
if(!vis[i])
{
e=i;
break;
}
return sg[x]=e;
}