【题目描述】:
Ymq和hy正在玩一个数字游戏,其中某人(恩~)暗暗请你帮助她获胜。这个游戏是这样的。一开始有一个数n(1<=n<=1000000),两个人轮流对n进行操作。每次可将n减去它的最大或最小的非零数位。比如3014最大的数位是4,最小的是1,于是它可以减去4或者1,分别产生3010和3013。直到n变成0时停止,谁将n变为0则获胜。
根据某种RP因素,游戏都由hy先做。
【输入说明】:
第一行是一个整数G(1<=G<=100),表示她们玩了G局游戏;
接下来G行每行是一个数n。
【输出说明】:
一共G行,每行输出一串字符。Hy赢了则输出hy,ymq赢了则输出ymq。
【输入样例】:
9
10
【输出样例】:
hy
ymq
解析:
这是典型的博弈问题,即如果存在必胜策略,那么就走必胜策略。
先预处理出每一个数字的最大值和最小值。用布尔数组f[i]表示对于数字i的输赢状况,f[i]:=(not f[i-max[i]]) or (not f[i-min[i]),它的含义是如果它能达到的两个值都是必败状态,那么他才是必败,如果有一个是必胜,那么它就是必胜。
由于,hy先操作,所以true是hy胜利,否则是ymq
code:
program sdf; var g,i,n,j : longint; f : array[1..1000000] of boolean; max,min : array[1..1000000] of byte; procedure deal(x : longint); var s : string; t,i : longint; begin s:=''; str(x,s); for i:=1 to length(s) do begin t:=ord(s[i])-ord('0'); if t>max[x] then max[x]:=t; if (t<min[x]) and (t<>0) then min[x]:=t; end; end; { deal } procedure work; begin fillchar(min,sizeof(min),127); for i:=1 to 1000000 do deal(i); for I:=1 to 9 do f[i]:=true; for i:=10 to 1000000 do f[i]:=(not f[i-max[i]]) or (not f[i-min[i]]); end; { work } procedure init; begin readln(g); for i:=1 to g do begin readln(n); if f[n] then writeln('hy') else writeln('ymq'); end; end; { init } begin assign(input,'cdgame.in'); reset(input); assign(output,'cdgame.out'); rewrite(output); work; init; close(input); close(output); end.