Hdu1404 Digital Deletions




题意: 给定一串序列,每次可以删除0右边的数或者把最右边的数改为比他小的数。

开始不会,搜的题解,完全没想到SG函数,哎!


由于题目给定的序列不长,最多就是只有1e6,可以直接暴力打个1~1e6的SG函数值。然后最后只需要根据当前的SGh函数值判断就行。关于这个怎么打SG 函数的表我其实也不太会,反正别人的代码写的挺好,我肯定想不到了。


#include<cstdio>
#include<cstring>
using namespace std;


int sg[1020000];
int get_lenth(int x)
{
    if(x<=9)  return 1;
    else if(x>=10&&x<=99)  return 2;
    else if(x>=100&&x<=999)  return 3;
    else if(x>=1000&&x<=9999)  return 4;
    else if(x>=10000&&x<=99999)  return 5;
    else return 6;
}
void SG(int n)
{
    int len=get_lenth(n);
    for(int i=len;i>=1;i--)   //每一个位上加上一个数 
    {
        int m=n;
        int base=1;
        for(int j=1;j<i;j++)
           base*=10;
        int tmp=m%(base*10)/base;   
        for(int k=tmp;k<9;k++)   
        {
            m+=base;
            sg[m]=1;
        }
    }
    if(len<6)     //小于6时末尾加0。
    {
        int m=n;
        int base=1;
        for(int i=len;i<6;i++)
        {
            m*=10;
            for(int k=0;k<base;k++)
                sg[m+k]=1;
            base*=10;
        }
    }
}
void Init()
{
    memset(sg,0,sizeof sg);
    sg[0]=1;
    for(int i=1;i<1000000;i++)
        if(!sg[i])   SG(i);
}
int main()
{
    Init();
    int n;
    char ch[8];
    while(scanf("%s",ch)!=EOF)
    {
        if(ch[0]=='0')   
        {
            puts("Yes");
            continue;
        }
        int len=strlen(ch);
        n=0;
        for(int i=0;i<len;i++)
        {
            n*=10;
            n+=ch[i]-'0';
        }
        if(sg[n])  puts("Yes");
        else puts("No");
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值