Lua 八皇后问题

From: http://www.waitingfy.com/archives/978

1.什么是八皇后问题?

 

八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后不知道你们玩过国际象棋没有。皇后在国际象棋中是非常重要的棋子,因为她的移动范围很广,比车,和象都要广,可以横竖走,斜着也可以走,一般死掉皇后,基本就输了。因为每一行都有8种可能,所以一共可能解是8*8*8*8*8*8*8*8所以要想人工在棋盘上摆出八个皇后的所有解,还是蛮难的一件事情。八皇后有很多方法解,最普遍的是用递归来解,但不要忘了递归是很慢的方式。

 

2.用Lua来解这个问题solution

 

用什么语言解不是重点,主要我最近在看《Programming in lua》这书,书中给出了答案,感觉写的比较好。第一眼看起来还蛮难的,又是递归!

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
local N = 8
-- 判断从第1行开始直到当前给定的行,列是否有冲突的皇后
-- 比如一个解{3, 7, 2, 1, 8, 6, 5, 4}, 在判断第4行,第一列是否合法是, isPlaceOK(a, 4, 1)
-- 我们就发现它是与第三行的2有 "斜着" 冲突
local function isPlaceOK(a,row,column)
    for i = 1, row - 1 do
       if (a[i] == column) or                      --相同列
         (a[i] - i == column - row) or        --斜着冲突, 方向是\
         (a[i] + i == column + row) then  --斜着冲突, 方向是/
         return false
       end
    end
    return true
end
 
-- 打印一个解
-- 我们这里的解是放在一个table中,类似{3, 7, 2, 1, 8, 6, 5, 4}
local function printSolution(a)
    for i = 1, N do
       for j = 1, N do
          io.write(a[i] == j and "X" or "-" , " " )
       end
       io.write( "\n" )
    end
    io.write( "\n" )
end
 
--核心方法,独立解释
local function addQueen(a, row)
    if row > N then
      printSolution(a)
    else
      for column = 1, N do
        if isPlaceOK(a, row, column) then
          a[row] = column
          addQueen(a, row + 1)
        end
      end
    end
end
 
addQueen({}, 1)--从第一行开始求解

 

3.程序输出

 

 

4.解释下addQueen这个函数

 

 

首先这个程序的解的样式是这样的:{3, 7, 2, 1, 8, 6, 5, 4},表示第1行的第3列摆了一个皇后,第2行的第7列摆了一个皇后,后面的以此类推。

首先我们要知道总的可能解是8个8相乘,所以我们要搞一个递归函数来判断8*8*8*8*8*8*8*8个可能解中是否有符合要求的解。 递归主要要处理要退出条件参数的问题,参数一般不是递增就是递减。我们这里选择从第一行开始放皇后求解,那么参数就是行,每次递增,退出条件就是第9行。每一行,我们要判断8个列中是否能找到合法解,如果能找到合法解,继续往下一行搜索,直到到达函数的退出条件就算是找到一个解了。总的可能解脑补下就是8*8*8*8*8*8*8*8,符合我们的期望。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值