2011-12-26 11:43:27
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1404
题意:一个字符串,每次可以把其中任何一个非0数码变成比它小的数码,或把一个0数码以及其右边的所有数码删掉。最后操作的人获胜,问先手是否能必胜。
mark:因为数据量实在很小,所以直接爆搜就好了。但是要用上字符串哈希、记忆化搜索,否则还是会TLE的。
跑了400+ms。
代码:
# include <stdio.h>
# include <string.h>
int dp[2000010] ;
int tab[] = {0, 0, 10, 110, 1110, 11110, 111110} ;
int hash (char *str)
{
int len = strlen (str) ;
int rtn = 0 ;
while (*str)
{
rtn = rtn * 10 + (*str -'0') ;
str++ ;
}
return rtn + tab[len] ;
}
int test (char str[])
{
int i, idx = hash(str) ;
char ch, j ;
if (dp[idx] != -1) return dp[idx] ;
if (str[0] == '0') return dp[idx] = 1 ;
for (i = 0 ; str[i] ; i++)
{
if (str[i] == '0')
{
str[i] = '\0' ;
if (test (str)==0) return dp[idx] = 1 ;
str[i] = '0' ;
}
else
{
ch = str[i] ;
for (j = '0' ; j < ch ; j++)
{
str[i] = j ;
if (test (str) == 0) return dp[idx] = 1 ;
}
str[i] = ch ;
}
}
return dp[idx] = 0 ;
}
int main ()
{
int i ;
char str[10] ;
memset (dp, -1, sizeof(dp)) ;
for (i = 0 ; i < 9 ; i++) dp[i] = 1 ;
dp[1] = 0 ;
while (gets(str))
puts (test(str)?"Yes" : "No") ;
}