HDU 1404 Digital Deletions

来源:互联网 发布:sql语句exists用法 编辑:程序博客网 时间:2024/06/07 10:13

题目链接:http://acm.hust.edu.cn/vjudge/problem/29195/origin


题意:有一些数,每次操作:1、可以选择一个位置,将其数变为比原来小的非负数。2、如果一个位置是0,可以把包括该位置以内以及所有右边的数去掉。不能操作的人输。


思路:长度不超过6,因为可以先打一个状态表。注意一点,如果第一个位置是0,那么先手必胜,而且打表取数时也不可以把第一个位置取为0(否则必败)。

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod 100000007bool f[1000009];void init(){    f[0] = true;    int digit[10];    int v[10];    int temp,len;    int now;    v[1] = 1;    rep(i,2,6) v[i] = v[i-1] * 10;    rep(i,1,999999)    {        bool ans = false;        temp = i;        now = len = 0;        while( temp )            digit[++len] = temp % 10 , temp/=10;        Rrep(j,len,1) //枚举每一位        {            if (digit[j]==0) ans |= !f[now];            else            {                int up;                if ( j == len )                    up = digit[j]-1;                else up = digit[j];                rep( k , 1 , up ) //枚举取多少                    ans |= !f[ i - k * v[j] ];            }            now = now * 10 + digit[j];        }        f[i] = ans;    }}int main(){    char s[10];    Clean(f,0);    init();    while(~scanf("%s",s))    {        if ( s[0] == '0' )            puts("Yes");        else{            int len = strlen(s);            int now = 0;            rep(i,0,len-1)                now = now * 10 + s[i] - '0';            puts( f[now]==0 ?"No":"Yes" );        }    }    return 0;}


0 0