Description
贝茜和约翰在玩一个数字游戏.贝茜需要你帮助她.
游戏一共进行了G(1≤G≤100)场.第i场游戏开始于一个正整数Ni(l≤Ni≤1,000,000).游
戏规则是这样的:双方轮流操作,将当前的数字减去一个数,这个数可以是当前数字的最大数码,也可以是最小的非0数码.比如当前的数是3014,操作者可以减去1变成3013,也可以减去4变成3010.若干次操作之后,这个数字会变成0.这时候不能再操作的一方为输家. 贝茜总是先开始操作.如果贝茜和约翰都足够聪明,执行最好的策略.请你计算最后的赢家.
比如,一场游戏开始于13.贝茜将13减去3变成10.约翰只能将10减去1变成9.贝茜再将9减去9变成0.最后贝茜赢.
Input
第1行输入一个整数G,之后G行一行输入一个Ni.
Output
对于每一场游戏,若贝茜能赢,则输出一行“YES”,否则输幽一行“NO”
Sample Input
2
9
10
9
10
Sample Output
YES
NO
NO
HINT
For the first game, Bessie simply takes the number 9 and wins.
For the second game, Bessie must take 1 (since she cannot take 0), and then
FJ can win by taking 9.
模拟(dp?)
先算出一个数字能减的数字
然后从以前的状态转移而来
在自己先手的时候如果能把数字改成先手必输的状态,那么这个状态先手必胜
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<ctime> #include<set> #define LL long long #define MX 1000010 using namespace std; inline LL read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool win[1000010]; int T,n,mx,mn; int main() { scanf("%d",&T); for (int i=1;i<=9;i++)win[i]=1; for (int i=10;i<=MX;i++) { int s=i,t; mx=-1;mn=10; while (s) { t=s%10; if (t>mx&&t)mx=t; if (t<mn&&t)mn=t; s/=10; } if (mx!=-1)win[i]|=(!win[i-mx]); if (mn!=10)win[i]|=(!win[i-mn]); } while (T--) { int x=read(); if (win[x])printf("YES\n"); else printf("NO\n"); } }
——by zhber,转载请注明来源