回 帖 发 新 帖 刷新版面

主题:[讨论]我的跳马格,大家PP

[问题描述]
     设有一个n*m的棋盘(2<=n<=50,2<=m<=50),找出从左下到右上的最短路径步数和路径。马走的规则为:1、马走日字;2、马只能向右走。

[输入样例]
4 4

[输出样例]
3
(1,1)->(2,3)->(4,4)

我用Delphi写的,不足之处请大家指出~~~~~~~~~

代码如下:

program tiaoma2;
{$APPTYPE CONSOLE}
const
  fi:array[1..4]of integer=(1,2,2,1);
  fj:array[1..4]of integer=(2,1,-1,-2);  {方向矢量}
type
  stp=record                     {位置}
        x,y:integer;
    end;
  steps=record
        len:integer;             {步数}
        sp:array[1..1000]of stp; {每步位置}
    end;
var
  n,m:integer;
  step:array[0..9999]of steps;        {搜索使用的队列}
  used:array[1..50,1..50]of boolean;    {记录访问过的点}
procedure print(d,k:integer);          {输出过程}
  var i:integer;
  begin
    writeln(k); write('(1,1)');
    with step[d] do
      for i:=2 to k do
        with sp[i] do
          write('->(',x,',',y,')');
    readln;
    halt                      {退出程序}
  end;                     {Endprint}
procedure bfs;               {广搜过程}
  var s,e,i,ti,tj,sx,sy:integer;
  begin
    with step[0] do
    begin sp[1].x:=1; sp[1].y:=1; len:=1 end;
    fillchar(used,sizeof(used),0); s:=0; e:=1; used[1,1]:=true;   {初始化}
    repeat              {广搜循环}
      with step[s] do
        with sp[len] do
        begin
          sy:=y;         {记录上一步的坐标(为了省去反复读内存的时间)}
          sx:=x
        end;                                                              {Endwith}
      if(sx=n)and(sy=m)then print(s,step[s].len); {如果已跳到,那么输出}
      for i:=1 to 4 do                      {搜索所有可能}
      begin
        ti:=sx+fi[i]; tj:=sy+fj[i];         {临时新坐标}
        if(ti in[1..n])and(tj in[1..m])     {如果临时坐标在范围内,且未访问}
          and(not used[ti,tj])then
        begin
          used[ti,tj]:=true;                         {不再访问该坐标}
          step[e]:=step[s];   {在原来基础上操作(为了省去反复读内存的时间)}
          with step[e]do
          begin
            inc(len);         {步数累加}
            with sp[len]do
            begin
              x:=ti;          {记录新坐标}
              y:=tj
            end               {Endwith}
          end;                {Endwith}
          e:=(e+1)mod 10000   {要访问的结点入队}
        end                   {Endif}
      end;                    {Endfor}
      s:=(s+1)mod 10000       {访问过的结点出队}
    until s=e  {如果所有可能都搜索过,且没找到(找到会自动跳出),结束搜索}
  end;          {EndBFS}
procedure no;    {如果没有结果,才执行这个过程}
  begin
    writeln('Not found!');
    readln
  end;        {Endno}
begin         {Main}
  readln(n,m);
  bfs;    {广度优先搜索}
  no
end.

回复列表 (共2个回复)

沙发

看上去很好,就是我这水平读不懂.

板凳

不会吧,注释应该很全了吧~~~~~~~~~~~~~

大家给我提提意见吧,有分加~~~~~~~~~~~~~~~

我来回复

您尚未登录,请登录后再回复。点此登录或注册