当前位置:编程学习 > C/C++ >>

杭电 1404

 
 
题意:有一个字符串(由 0--9 组成 ),两个人轮流改变字符串的值,谁最后将字符串改成无,就赢。
 
规则:
 
1:可以修改任意一个值,可将该值修改成小于它的任意一值。(例:str=“1234”,可将4改成0或1或2或3,也可以将3改成0,或1,或2)
 
2:每次只能改一个值
 
3:假如碰到0,可以将0和其右边的值消掉。(例:str=“1023”,可以变成str=“1”)
 
 
 
思路:博弈题型,所以就求SG值就行了,SG值为0 的必输,反之必赢。
 
可将字符串当整数处理,但是,必须记得,这是字符串,不是真正的整数。
 
先声明一下将字符串变整数的规则:
 
1:字符串"1234"可以当成整数1234处理
 
2:以0开头的字符串统一当成字符串"0"处理,且其SG值为1(因为这是比胜态)。
 
 
 
根据游戏规则,来讲讲怎么求每个字符串的后继:
 
例:str=”1023“
 
先改3的值,可以变成:"1022","1021","1020"。
 
改2的值,可以变成:"1013","1003"。
 
改0的值,变成:"1"。
 
改1的值,可以变成:"0023"。
 
 
 
代码:
 
[cpp]  
#include<stdio.h>  
#include<string.h>  
#include<stdlib.h>  
  
int sg[1000000];  
  
int getint(char *str)//返回字符串的整型值  
{  
    int num=0;  
    int length=strlen(str);  
    int j;  
    for(j=0;j<length;j++)  
    {  
        num=num*10+(str[j]-48);  
    }  
    return num;  
}  
  
int mex(char *str)  
{  
    int a[55]={0};//最多54个后继  
    int length = strlen(str);  
    int i,j,keep,num;  
    for(i=length-1;i>=0;i--)//扫描所有后继  
    {  
        if( str[i]==48 )  
        {  
            if( i==0 )//必胜态  
            {  
                a[1]=1;  
            }  
            else  
            {  
                  
                str[i]=0;  
                num=getint(str);  
                if( sg[ num ]==-1)  
                    sg[ num ]=mex(str);  
                a[ sg[ num ] ]=1;  
                str[i]=48;  
            }  
            continue;  
        }  
        for(j=str[i]-1;j>=48;j--)  
        {  
            keep=str[i];//保存一下原值  
            str[i]=j;  
              
            if(j==48)  
            {  
                if( i==0 )//这是必胜态  
                {  
                    a[1]=1;  
                }  
                else  
                {  
                    num=getint(str);  
                    //str[i]=0;  
                    if( sg[ num ]==-1)  
                        sg[ num ]=mex(str);  
                    a[ sg[ num ] ]=1;  
                }  
            }  
            else   
            {  
                num=getint(str);  
                if( sg[ num ] == -1 )  
                {  
                    sg[ num ]=mex(str);  
                }  
                a[ sg[ num ] ]=1;  
            }  
              
            str[i]=keep;//还原数值  
        }  
          
    }  
    for(i=0;i<55;i++)  
        if(a[i]==0)  
            return i;  
}  
  
int main()  
{  
    int i;  
    char str[7];  
    memset(sg,-1,sizeof(sg));  
    sg[0]=1;  
    while( gets(str) )  
    {  
          
        if(str[0]==48)//这是必胜态  
        {  
            printf("Yes\n");  
            continue;  
        }  
        if( sg[ getint(str) ]==-1 )  
        {  
            sg[ getint(str) ]=mex(str);  
        }  
        if( sg[ getint(str) ]==0 )  
            printf("No\n");  
    &n
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,