zoukankan      html  css  js  c++  java
  • Hdu 1404 Digital Deletions

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1404

    刚开始想采取找规律的方法解题,可以没有发现规律。无奈,只好采用求PN点的方法。

    我们假设数字最右边为第一位,且为最低位。那么可以知道当最高位为0时,那么先手的人必定能胜利,这个可以作为一个剪枝条件。

    接下来就是两种操作了:1.降低其中任何一位

                 2.把其中一个0及这位0后面所有的数字删去

    我们只需通过这两个操作,寻找目标数字的后续数字状态的PN状态,即可求得目标数字的PN状态。其实我们只需判断后续状态中有没有P点就行了,如果有P点,那么目标数字的状态为N点。如果没有N点,那么目标数字的状态为P点。通过这方法,就可以求得题目要求数字的PN状态了。

    #include <iostream>
    #include <cstring>
    #include <sstream>
    #include <cstdio>
    
    using namespace std;
    
    const int MAXN = 1000000 + 5;
    int sg[MAXN];
    
    stringstream ss;
    int length ;
    
    inline int Get_digit( int num, int i ) // 求出数字第i位数,最右边为第1位
    {
        switch (i){
            case 1: return num%10;
            case 2: return num%100/10;
            case 3: return num%1000/100;
            case 4: return num%10000/1000;
            case 5: return num%100000/10000;
            default : return num/100000;
        };
    }
    
    int Get_sg( int num ) // 求sg值
    {
        if( sg[num]!=-1 )
            return sg[num];
        int temp = 1;
        int orignal = num;
        int i;
        for( i=0;i<length-1;i++ ) // 缩小第i位的值
        {
            num = orignal;
            if( Get_digit( num, i+1 )==0 )
            {  // 消去0即后面所有的数
                if( Get_sg( num/( temp*10 ) )==0 ) // 发现必败点
                {
                    sg[ orignal ] = 1;  // 则此点为必胜点
                    return 1;
                }
            }
            num = orignal;
            while( Get_digit( num, i+1)!=0 )
            {
                num = num - temp;
                if( Get_sg( num )==0 ) // 发现必败点
                {
                    sg[ orignal ] = 1; // 则此点为必胜点
                    return 1;
                }
            }
            temp = temp * 10;
        }
    
        num = orignal;
        while( Get_digit(num, length)>1 ) // 最高位单独处理
        {     // 避免出现 类似于  123 -> 23 的情况
                num = num - temp;
                if( Get_sg( num )==0 ) // 发现必败点
                {
                    sg[ orignal ] = 1; // 则此点为必胜点
                    return 1;
                }
        }
        sg[orignal] = 0; // 没有发现必败点,则此点即为必败点
        return 0;
    }
    
    int main()
    {
        memset( sg, -1,sizeof(sg) );  // 初始化
        char in[10];
        int num, ans;
        sg[0] = 1;
        sg[1] = 0;  // 初始化
        while( scanf("%s", in)!=EOF )
        {
            if( in[0]=='0' ) // 最高为为0, 则一定胜利
            {
                printf( "Yes
    " );
                continue;
            }
            ss.clear();
            ss << in;
            ss >> num; // char转int
            length = strlen(in);  // 求该数字的长度
            ans = Get_sg( num );
            if( ans )
            {
                printf( "Yes
    " );
            }
            else
            {
                printf( "No
    " );
            }
        }
        return 0;
    }
    
  • 相关阅读:
    [Windows]wmic查看运行进程的参数
    Java8中的foreach跳出循环break/return
    Python Learning(6)字典
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(三): 整合阿里云 OSS 服务 -- 上传、下载文件、图片
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(四): 整合阿里云 短信服务、整合 JWT 单点登录
    SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇(五): 数据表设计、使用 jwt、redis、sms 工具类完善注册登录逻辑
    Servlet、Jsp
    BIO、NIO、AIO
    HashMap (JDK1.8) 分析
    mysql常见笔试题
  • 原文地址:https://www.cnblogs.com/Emerald/p/4065394.html
Copyright © 2011-2022 走看看