HDU 1404 Digital Deletions

题目链接: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");

    }

}

  

你可能感兴趣的:(git)