sg函数 hdu 1404 Digital Deletions
题目大意;给一个字符串,长度6以内,由0~9组成,有两个操作,每次进行一个, 把任意位上的非0的数变成一个比他小的数,例如1256 ,对5操作,把5变成 0,1,2,3,4,中任意一个,如果该位为0,则删除该位及后面所有位.sg 暴力dfs#include#include#include#includeusing namespace std;const
·
题目大意;
给一个字符串,长度6以内,由0~9组成,有两个操作,每次进行一个, 把任意位上的非0的数变成一个比他小的数,
例如1256 ,对5操作,把5变成 0,1,2,3,4,中任意一个,如果该位为0,则删除该位及后面所有位.
sg 暴力dfs
#include <cstdio>
#include <cstring>
#include <cmath>
#include <istream>
using namespace std;
const int maxn = 1000500;
char str[10];
int sg[maxn];
///得到n个0
inline int getten(int i){
switch(i){
case 1:return 1;
case 2:return 10;
case 3:return 100;
case 4:return 1000;
case 5:return 10000;
case 6:return 100000;
case 7:return 1000000;
}
return 1;
}
inline int getNpos(int x,int const &pos){
x %= getten(pos+1);
x /= getten(pos);
return x;
}
int DFS(int const &state){
//如果已经判断过了
if (sg[state] != -1) return sg[state];
//N状态
if (state == 0) return 1;
int t_state = state;
//得到位数
int l = 0;
while(t_state)
l++,t_state /= 10;
for (int i = l;i >= 1;--i){
t_state = state;
const int temp = getNpos(state,i);
if (temp){
//该位上的数依次减1
for (int j = 1;j < temp;++j){
t_state -= getten(i);
//能得到P状态,说明此时是N状态
if ( DFS(t_state) == 0){
t_state+= j*getten(i);
return 1;
}
}
//判断是不是首位,首位不能减到0
if (i != l){
t_state -= getten(i);
if ( DFS(t_state) == 0){
t_state+= temp*getten(i);
return 1;
}
t_state += temp*getten(i);
}else
t_state += (temp-1)*getten(i);
}else{
//如过该位是0
int tt_state = t_state % getten(i-1);
t_state /= getten(i+1);
if ( DFS(t_state)== 0){
t_state *= getten(i+1);
t_state += tt_state;
return 1;
}
t_state *= getten(i+1);
t_state += tt_state;
}
}
return sg[state] = 0;
}
int main(){
fill(sg,sg+maxn,-1);
sg[0] = 1;
sg[1] = 0;
for (int i = 2;i <= 999999;++i)
sg[i] = DFS(i);
//因为输入有前导0,所以要存字符串
while( scanf("%s",str) != EOF ){
//如果前导0,直接获胜
if (*str == '0'){
puts("Yes");
continue;
}
int st;
sscanf(str,"%d",&st);
if ( sg[st] ) puts("Yes");
else puts("No");
}
return 0;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)