hdu1404(sg的应用)

题意:对一个数字进行两种操作:1、去掉0及其后面的数字;2、将数字的某一位变小,进行最后一步操作的玩家胜出
用sg函数的思想来做,sg = 0表示先手必败状态,那么它的后继状态的sg = 1

代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>

#define N 1000000 + 5
#define inf 0x7fffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
int sg[N];

int get_length(int n)//求n的位数
{
    int k = 0;
    while(n)
    {
        n/=10;
        k++;
    }
    return k;
}
void _extend(int n)
{
    int len =  get_length(n);
    int i;
    int base = 1;
    for(i = 0; i < len; i++)//将某一位变大得到的数字是必胜状态
    {
        int m = n;
        int temp = (m%(10*base))/base;
        m -= temp*base;
        for(int j = temp+1;j <= 9; j++)
        {
            int k = m + j*base;
            sg[k] = 1;
        }
        base*=10;
    }
    if(len != 6)//在n后面补上0。。。得到的是必胜状态
    {
        base = 1;
        while(get_length(n) != 6)
        {
           n*=10;
           for(i = 0; i < base;i++)
               sg[i+n] = 1;
            base*=10;
        }

    }

}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
    int i;
    memset(sg,0,sizeof(sg));//sg[i] = 0 状态i是前者必败状态
    sg[0] = 1;//这里是前者必胜
    for(i = 1 ; i < 1000000; i++)
    {
         if(!sg[i])
            _extend(i);
    }

    char str[10];
    while(scanf("%s",str) != EOF)
    {
        if(str[0] == '0') {
            printf("Yes\n");
            continue;
        }
        int n = 0, i;
        for(i = 0; i < strlen(str); i++)
            n = n*10 + str[i] - '0';
        if(sg[n]) printf("Yes\n");
        else printf("No\n");
    }


    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值