【题目描述】:

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。

【输入样例】:

2

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.
posted on 2012-03-15 12:28  淡·雅·墨  阅读(428)  评论(0编辑  收藏  举报