这个题说用到sg有点牵强 , 我个人以为我所了解的sg是和Nim博弈连在一起的。
该题只是暴力出结果, 存起来。
该题的分两种情况。
①第一种情况是该串数的第一位是0,只要第一位是0 肯定是必胜点。
② 第二种情况是第一位不是0, 那吗这一串数就可以看成一个数。
1肯定是必败点。
然后,从1暴力到999999。
如果这个状态是必败点, 那么你就暴力找他的前继状态(即操作一步能达到该状态的情况), 众所周知,只要一步能达到必败点的状态肯定为必胜点。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e6;
int sg[maxn];
char str[8];
int getlen(int x)
{
int len = 0;
while(x)
{
len++;
x/=10;
}
return len;
}
void Sg()
{
memset(sg, 0, sizeof(sg));
sg[0]= 1;
sg[1] = 0;
for(int i = 1;i < maxn;i++)
{
if(sg[i])continue;
int l = getlen(i);
int base = 1;
for(int j = 0;j < l;j++)// 比他大的 一步能达到他的 为必胜点
{
int num = i;
num/=base;
int b = num%10;
for(int k = 1;k +b <= 9;k++)
{
sg[i+ base*k] = 1;
}
base *=10;
}
int num1 = i;
base = 1;
for(;l < 6;l++)
{
num1*=10;
for(int k= 0;k < base;k++)
{
sg[num1+k] = 1;
}
base*=10;
}
}
}
int main()
{
Sg();
while(~scanf("%s", str))
{
if(str[0] == '0')printf("Yes\n");
else
{
int num = 0;
for(int i = 0;str[i]!= '\0';i++)
num =num*10+str[i]-'0';
if(sg[num])printf("Yes\n");
else printf("No\n");
}
}
return 0;
}