V

来源:互联网 发布:度然后知长短的度 编辑:程序博客网 时间:2024/04/26 11:41

V - Digital Deletions HDU-1404

题意:

​ 给出一个不超过6位的数字(有可能会出现前导零),有两种操作:

1. 更改某一位的数字比其原来的小2. 如果某一位是0可以将其和之后的数字删除

例如:

img

两个人在玩游戏,谁先操作到最后谁获胜。

思路:

​ 此题可以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;}