回 帖 发 新 帖 刷新版面

主题:马踏棋盘--觉得自己编程够强的进来

8*8的一个国标象棋棋盘,上有一匹马,刚好走63步,从一开始指定的位置,踏遍棋盘上所有的位置。如何编程求解?

回复列表 (共10个回复)

沙发

我不强,但照样会。
搜索加剪枝加半启发式,n=30以内回车出解没问题(只输出一个解)。
如果n只有8,加上一个很小的剪枝就可以回车出解。
   1  40  35  64  47  42  13  10
  34  63   2  41  14  11  46  43
  39  36  25  48   3  44   9  12
  62  33  50  37  26  15   4  45
  51  38  27  24  49   6  19   8
  32  61  54  57  28  21  16   5
  55  52  59  30  23  18   7  20
  60  31  56  53  58  29  22  17

   1  52  35  64  45  50  13  10
  34  63   2  51  14  11  46  49
  53  36  25  44   3  48   9  12
  62  33  42  37  26  15   4  47
  41  54  27  24  43   6  19   8
  32  61  38  57  28  21  16   5
  55  40  59  30  23  18   7  20
  60  31  56  39  58  29  22  17

   1  36  45  64  29  34  13  10
  46  63   2  35  14  11  30  33
  37  44  25  28   3  32   9  12
  62  47  38  53  26  15   4  31
  43  54  27  24  39   6  19   8
  48  61  40  57  52  21  16   5
  55  42  59  50  23  18   7  20
  60  49  56  41  58  51  22  17

贴上来3个解先,瞬间出的。

板凳

求全部解吧,6阶;)

3 楼

6阶,起点为(1,1)时有401654种解,耗时10s,生成的输出文件60.5M

4 楼

老实说,我不强
来看看的目的是想瞻仰一下强人的形象的
很仰慕“搜索加剪枝加半启发式”这高深的理论
可惜高人不指点,学习不到绝技
我有点愚笨,不懂得其中的什么道理
不过我不会自卑
脚踏实地安份做人是我的本性
按回车后我用了八十多秒才把八立方的马位找出来
我搞了一个中午,头晕脑涨了,脑袋退化了不好使
还望各位高人对小子多多指点

DEFINT A-Z
a1# = TIMER
n = 8
m = n * n
DIM s(n, n), p(m, 2)
q = 1         '  '起点,很重要的一个标志
p(q, 1) = 1
p(q, 2) = 1
s(1, 1) = 1

DO
'找下一个位置
q2 = q + 1
IF p(q, 0) > 7 THEN  '八个马位全部跳完
p(q, 0) = 0
s(p(q, 1), p(q, 2)) = 0
q = q - 1
p(q, 0) = p(q, 0) + 1
ELSE
p(q2,1)=p(q,1)+p(q,0)\2-2-(p(q,0)>3) '一个马总共有八个方向可以跳
p(q2,2)=p(q,2)+((p(q,0)MOD 2)*2-1)*(3-ABS(p(q2,1)-p(q,1)))
  '我把select语句简缩成这两句了,不知道会不会减慢速度
IF p(q2,1)<1 OR p(q2,2)<1 OR p(q2,1)>n OR p(q2,2)>n THEN
   p(q, 0) = p(q, 0) + 1
ELSEIF s(p(q2, 1), p(q2, 2)) > 0 THEN
   p(q, 0) = p(q, 0) + 1
ELSE
   q = q + 1
   s(p(q, 1), p(q, 2)) = q
END IF
END IF
LOOP UNTIL q = m

'得出结果
CLS
FOR i = 1 TO n
FOR j = 1 TO n
  PRINT USING "###"; s(i, j); '需要保存就写到文件去喽
NEXT
PRINT
NEXT

a2# = TIMER
PRINT "总共用了时间";a2# - a1#;"秒"

'如果一个结果不够的话,再在程序中加多一个do圈子就行了

'我不要评什么分,希望大家多多顶顶提点意见什么的。

5 楼

我算到6方5方都可以
4方以下就出错了,应该是没有4方以下的吧。

6 楼

楼上的程序太强了,我看不懂……当然,也可以认为我没认真看

7 楼

呵呵,在这里
过程已经不重要了
等有了结果过程才会有作用
有了兴趣才会有刨根的动力
老实说,我已经对很多事情都已经失去兴趣了
人,不要花心,要专心
(情也一样,哪怕是骗人骗自的)

8 楼

很简单的一个算法^^

9 楼

老说算法,我真不懂
但我有过程
我看过RichOne说过一个"挑选出口少的位置先跳"
我想了很久没想明白
后来我想到的是,把方向改一改变成根据位置动态来设置方向的优先,
一改,果然很快得到结果
再按照"挑选出口少的位置先跳"的思想,本来想让马尽量先跳边线,结果就不行了.

仔细一想,这可能是马的特点吧,我本来是想把四个角的方向扭曲来跳,正好歪打正着了.

defint a-z

  h = 8
  l = 8
  hl = h * l
  dim s(h, l, 2)
  x = 1
  y = 1
  n = 1

  cls
  locate 1, 3
  print 1
    do
        t1# = timer
        locate 23, 1
        print t1#;

        do
          s(x, y, 0) = s(x, y, 0) + 1
          if s(x, y, 0) > 8 then
             locate x, y * 3
             print "   ";
             s(x, y, 0) = 0
             x1 = x
             x = s(x1, y, 1)
             y = s(x1, y, 2)
             n = n - 1
          else
             k = s(x, y, 0)
             if y > (l - 3) then k = k + 2
             if x > (h - 3) then k = k + 2
             if y < 3 and x > 3 then k = k + 4
             select case (k mod 8)
                case 1: nx = x - 1: ny = y - 2
                case 2: nx = x - 2: ny = y - 1
                case 3: nx = x - 2: ny = y + 1
                case 4: nx = x - 1: ny = y + 2
                case 5: nx = x + 1: ny = y + 2
                case 6: nx = x + 2: ny = y + 1
                case 7: nx = x + 2: ny = y - 1
                case 0: nx = x + 1: ny = y - 2
             end select
             if nx > 0 and nx <= h and ny > 0 and ny <= l then
                if s(nx, ny, 0) = 0 then
                   s(nx, ny, 1) = x
                   s(nx, ny, 2) = y
                   n = n + 1
                   x = nx
                   y = ny
                   locate x, y * 3
                   print n;
                end if
             end if
          end if
loop until n >= hl

t2# = timer
locate 23, 30
print t2#, t2# - t1#,
zzz = zzz + 1
print zzz,
s(x, y, 0) = 9
loop until input$(1) = chr$(27)
end

10 楼

你是个非常认真的人。

我来回复

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