题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1404
题意:给出一个长度不超过6的数字(可能有前缀0)。两种操作:(1)将某一位数字变为比它小的任意一个数字;(2)删掉从某个数字0开始后面的所有数字。两个人轮流操作,谁删掉最后一个数字谁赢?
思路:从SG为0的数字更新,更新到的数字SG值均为1.
int n;
char s[10];
int SG[N];
int p[]={1,10,100,1000,10000,100000,1000000};
int getLen(int x)
{
if(x>=0&&x<=9) return 1;
if(x>=10&&x<=99) return 2;
if(x>=100&&x<=999) return 3;
if(x>=1000&&x<=9999) return 4;
if(x>=10000&&x<=99999) return 5;
return 6;
}
void DFS(int dep,int x,int L)
{
if(dep==L)
{
SG[x]=1;
return;
}
int i;
FOR0(i,10) DFS(dep+1,x*10+i,L);
}
void deal(int x)
{
int L=getLen(x);
int i,j,k=1;
int a[10],temp=x;
for(i=0;i<L;i++) a[i]=temp%10,temp/=10;
for(i=0;i<L;i++)
{
for(j=a[i]+1;j<10;j++) SG[x+k*(j-a[i])]=1;
k*=10;
}
if(L<6)
{
SG[x*10]=1;
x*=10;
L++;
for(i=1;i+L<=6;i++) DFS(0,x,i);
}
}
void init()
{
SG[0]=1;
int i;
for(i=1;i<=999999;i++) if(!SG[i])
{
deal(i);
}
}
int main()
{
init();
while(scanf("%s",s)!=-1)
{
n=strlen(s);
if(s[0]=='0')
{
puts("Yes");
continue;
}
int x=0,i;
FOR0(i,n) x=x*10+s[i]-'0';
int ans=SG[x];
if(ans) puts("Yes");
else puts("No");
}
}