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\n" );

            continue;

        }

        ss.clear();

        ss << in;

        ss >> num; // char转int

        length = strlen(in);  // 求该数字的长度

        ans = Get_sg( num );

        if( ans )

        {

            printf( "Yes\n" );

        }

        else

        {

            printf( "No\n" );

        }

    }

    return 0;

}

 

你可能感兴趣的:(git)