主题:马踏棋盘--觉得自己编程够强的进来
rickone
[专家分:15390] 发布于 2005-04-21 17:51:00
8*8的一个国标象棋棋盘,上有一匹马,刚好走63步,从一开始指定的位置,踏遍棋盘上所有的位置。如何编程求解?
回复列表 (共10个回复)
沙发
faintzw [专家分:2660] 发布于 2005-04-21 21:43:00
我不强,但照样会。
搜索加剪枝加半启发式,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个解先,瞬间出的。
板凳
rickone [专家分:15390] 发布于 2005-04-22 18:39:00
求全部解吧,6阶;)
3 楼
faintzw [专家分:2660] 发布于 2005-04-22 21:58:00
6阶,起点为(1,1)时有401654种解,耗时10s,生成的输出文件60.5M
4 楼
moz [专家分:37620] 发布于 2005-04-24 14:20:00
老实说,我不强
来看看的目的是想瞻仰一下强人的形象的
很仰慕“搜索加剪枝加半启发式”这高深的理论
可惜高人不指点,学习不到绝技
我有点愚笨,不懂得其中的什么道理
不过我不会自卑
脚踏实地安份做人是我的本性
按回车后我用了八十多秒才把八立方的马位找出来
我搞了一个中午,头晕脑涨了,脑袋退化了不好使
还望各位高人对小子多多指点
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 楼
moz [专家分:37620] 发布于 2005-04-24 14:47:00
我算到6方5方都可以
4方以下就出错了,应该是没有4方以下的吧。
6 楼
faintzw [专家分:2660] 发布于 2005-04-24 15:51:00
楼上的程序太强了,我看不懂……当然,也可以认为我没认真看
7 楼
moz [专家分:37620] 发布于 2005-04-24 16:22:00
呵呵,在这里
过程已经不重要了
等有了结果过程才会有作用
有了兴趣才会有刨根的动力
老实说,我已经对很多事情都已经失去兴趣了
人,不要花心,要专心
(情也一样,哪怕是骗人骗自的)
8 楼
lasanes [专家分:0] 发布于 2005-07-02 16:52:00
很简单的一个算法^^
9 楼
moz [专家分:37620] 发布于 2006-04-11 14:08:00
老说算法,我真不懂
但我有过程
我看过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 楼
rickone [专家分:15390] 发布于 2006-04-12 12:56:00
你是个非常认真的人。
我来回复