回 帖 发 新 帖 刷新版面

主题:[讨论]骑士游历问题


在n*n的国际象棋棋盘的某一位置(p,q)有一个马,用“马走日字”的规则,要求它不重复地走完所有格子。
输入:
n p q
输出:
一个n*n的矩阵,表示每个格子是第几个走到。


请问,这道大家很熟悉的题目除了回溯还有别的方法吗?

如有,最好有程序。谢谢![em1][em1]

回复列表 (共20个回复)

11 楼

同时也帮我看看我的程序怎么错了(有注释)。
TYPE
   arr1 = ARRAY[1..31, 1..31] OF INTEGER;
   arr2 = ARRAY[1..8, 1..2] OF INTEGER;
   arr3 = ARRAY[1..961] OF INTEGER;
VAR
  map, map2: arr1;
  {map、map2是地图
   map[i, j]存放地图上第i行第j列是否走过,走过为1,未走过为0
   map2[i, j]存放地图上一个已走过的位置:第i行第j列是第几个走到的}
  zx: arr2;
  {zx存放走向数据}
  step_a, step_i, step_j: arr3;
  {三个数组分别存放第step步的选择走法a以及位置}
  n, p, q, i, j, a, lsi, lsj, step: INTEGER;
BEGIN
    READLN(n, p, q);
    i := p; j := q;
    a := 0;
    zx[1, 1] := -2; zx[1, 2] := -1;
    zx[2, 1] := -1; zx[2, 2] := -2;
    zx[3, 1] := 1; zx[3, 2] := -2;
    zx[4, 1] := 2; zx[4, 2] := -1;
    zx[5, 1] := -2; zx[5, 2] := 1;
    zx[6, 1] := -1; zx[6, 2] := 2;
    zx[7, 1] := 1; zx[7, 2] := 2;
    zx[8, 1] := 2; zx[8, 2] := 1;
    step := 0;
    REPEAT
         a := a + 1;        {选择下一个走向}
         IF a <= 8 THEN BEGIN  {此走向有效]}
            lsi := i + zx[a, 1]; lsj := i + zx[a, 2];{试探前进}
            IF (lsi >= 1) AND (lsi <= n) AND (lsj >= 1) AND (lsj <= n) AND (map[lsi, lsj] = 0) THEN BEGIN      {这个位置可走}
               i := lsi; j := lsj;   {前进,各数据存入数组}
               step := step + 1;
               map2[i, j] := step;
               step_a[step] := a;
               map[i, j] := 1;
               step_i[step] := i; step_j[step] := j;
               a := 0;
            END;
         END ELSE BEGIN           {前进的走向无效}
            step := step - 1;     {后退一步}
            a := step_a[step]; i := step_i[step]; j := step_j[step]; {再搜索}
         END;
    UNTIL step = n * n;    {搜索完成}
    FOR i := 1 TO n DO BEGIN            {输出}
        FOR j := 1 TO n DO BEGIN
            WRITE(map2[i, j], ' ');
        END;
        WRITELN;
    END;
    READLN;
END.

我本以为没什么问题,谁知输出后总是向-1946、32823等一些乱七八糟的数字。
怎么回事?

12 楼

Matodied,"lsj := i + zx[a, 2]"这一句应该是"lsj := j + zx[a, 2]"吧

13 楼


我觉得你map1,map2只要一个就够了:走过的存底几步走的;没走的设0

我的谁给看看!!

14 楼

Matodied:
判断输入的n是否大于2(如果小于等于2是无法走的,这样节约一些时间);
我觉得你的REPEAT里的东东有些怪:这个
IF (lsi >= 1) AND (lsi <= n) AND (lsj >= 1) AND (lsj <= n) AND (map[lsi, lsj] = 0) THEN BEGIN      {这个位置可走}
               i := lsi; j := lsj;   {前进,各数据存入数组}
               step := step + 1;
               map2[i, j] := step;
               step_a[step] := a;
               map[i, j] := 1;
               step_i[step] := i; step_j[step] := j;
               a := 0;
            END;
         END ELSE BEGIN           {前进的走向无效}
            step := step - 1;     {后退一步}
            a := step_a[step]; i := step_i[step]; j := step_j[step]; {再搜索}
         END;
明明和回朔一样嘛,如果你这样写答案会有问题:还没到目标就被修改.

15 楼


其实判断与不判断都一样,节省不了太多时间。。

16 楼

我这里有回朔的,你想看吗?

17 楼


我的就是回溯的,可不知道为什么错了。。

18 楼

我是问你:需不需要?????????????????????????

19 楼


好吧,不过如果你能告诉我我的那里错了,我会更感激你的。

20 楼


对不住各位,我的那个骑士游历程序原先贴错程序了,我已经修改了,请你们再帮我看看!![em8][em8]

我来回复

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