V - Digital Deletions HDU-1404
题意:
给出一个不超过6位的数字(有可能会出现前导零),有两种操作:
1. 更改某一位的数字比其原来的小
2. 如果某一位是0可以将其和之后的数字删除
例如:
两个人在玩游戏,谁先操作到最后谁获胜。
思路:
此题可以sg打表,利用最简单的性质:同样逆推局面推出胜态。
用相反的操作,还原胜态。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
using namespace std;
const int maxn = 1000000;
char str[10];
int sg[maxn],n;
int getLen(int x)
{
int ans = 0;
while(x) {
x /= 10;
ans++;
}
return ans;
}
void FindWin(int now)
{
int m,base,len;
len = getLen(now);
for(int i = len;i >= 1; i--) {
m = now;
base = 1;
for(int j = 1;j < i; j++) base *= 10;
int tmp = (m%(base*10))/base;
for(int j = tmp;j < 9; j++) {
m += base;
sg[m] = true;
}
}
m = now;
base = 1;
for(int i = len;i < 6; i++) {
m *= 10;
for(int j = 0;j < base; j++)
sg[m+j] = true;
base *= 10;
}
}
void SG()
{
memset(sg,0,sizeof(sg));
for(int i = 1;i < maxn; i++) {
if(!sg[i]) FindWin(i);
}
}
int main()
{
//freopen("in.txt","r",stdin);
SG();
while(scanf("%s",str) != EOF) {
if(str[0] == '0') {
printf("Yes\n");
}
else {
n = 0;
int len = strlen(str);
for(int i = 0;i < len; i++) {
n *= 10;
n += str[i] - '0';
}
if(sg[n]) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}