Hdu1404 Digital Deletions(暴力SG博弈)

Digital Deletions

题意:一串由0~9组成的数字,可以进行两个操作:1、把其中一个数变为比它小的数;2、把其中一个数字0及其右边的所以数字删除。两人轮流进行操作,最后把所以数字删除的人获胜,问前者胜还是后者胜。字符串长度为1-6,前者胜输出Yes,否则输出No.

题解:具体看代码。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn=1e6+10;
  7 char s[10];
  8 int sg[maxn];
  9 int get_sg(int x)
 10 {
 11     int t=x;
 12     int cnt=0;
 13     int num[10]={0};
 14     while(t)
 15     {
 16         num[++cnt]=t%10;
 17         t/=10;
 18     }
 19     int flag=0;
 20     for(int i=1;i<=cnt;i++)//最外层for循环控制x的每一位的所有操作 
 21     {
 22         if(num[i]==0)//当前这一位为0,那么对这一位能进行的操作只能是抹去 
 23         {
 24             //以下判断将该位抹去后的状态是否为必胜态 
 25             int k=0;
 26             for(int j=cnt;j>i;j--)
 27             {
 28                 k=k*10+num[j]; 
 29             }//例如x=970,我们求得K=97(97是将0抹去后的状态) 
 30             if(!sg[k])//如果97为必败态,那么970一定为必胜态 
 31                 flag=1; 
 32         }
 33         else//当前这一位不为0 
 34         {
 35             //例如x=452 它一步可以到达的状态有 451 450 442 432 422 412 402 352 252 152 (052) 
 36             //因为如果第一位是0的话,面对这种状态的人必胜,我们需要判断它可以一步到达的状态是否有必败态,所以不用考虑第一位是0的
 37             //反而如果考虑了第一位是0就会出错 比如402,对于第一位来说,它的下一步状态之一是002,是必胜态,但是我们再判断的时候,判断的
 38             //其实是2,2是必败态,因此出错。 
 39             if(i==cnt)//即为第一位 
 40             {
 41                 for(int j=1;j<num[i];j++)
 42                 {
 43                     int p=0;
 44                     for(int k=cnt;k>=1;k--)
 45                     {
 46                         if(k==i)
 47                         {
 48                             p=p*10+j;
 49                         }
 50                         else
 51                         {
 52                             p=p*10+num[k];
 53                         }
 54                     }
 55                     if(sg[p]==0)
 56                     {
 57                         flag=1;
 58                         break;
 59                     }
 60                 } 
 61                 
 62             }
 63             else
 64             { 
 65                 for(int j=0;j<num[i];j++)
 66                 {
 67                     int p=0;
 68                     for(int k=cnt;k>=1;k--)
 69                     {
 70                         if(k==i)
 71                         {
 72                             p=p*10+j;
 73                         }
 74                         else
 75                         {
 76                             p=p*10+num[k];
 77                         }
 78                     }
 79                     if(sg[p]==0)
 80                     {
 81                         flag=1;
 82                         break;
 83                     }
 84                 } 
 85             }
 86         }
 87         if(flag)
 88             break;
 89     }
 90     if(flag)
 91         return 1;
 92     else
 93         return 0;
 94 }
 95 int main()
 96 {
 97     int n;
 98     memset(sg,-1,sizeof(sg));
 99     sg[0]=1;
100     sg[1]=0;
101     for(int i=2;i<maxn;i++)
102     {
103         sg[i]=get_sg(i);
104     }
105     while(~scanf("%s",s))
106     {
107         if(s[0]=='0')
108         {
109             puts("Yes");
110             continue;
111         }
112         else
113         {
114             int sum=0;
115             int len=strlen(s);
116             for(int i=0;i<len;i++)
117             {
118                 sum=sum*10+s[i]-'0';
119             }
120             if(sg[sum])
121                 puts("Yes");
122             else
123                 puts("No");
124         }
125     }
126 }
原文地址:https://www.cnblogs.com/1013star/p/9857544.html