Lua实现的八皇后问题
来自《Lua程序与设计》第二节- 八皇后问题
输出所有解的解法
书中提供的源代码,加注了自己的注释。
N = 8
--[[
N为棋盘规模
a为一维数组,保存第i个皇后所在的列数
]]
-- 检查是否可以将第n个皇后放在第n行第c列(前n-1行的皇后已经放好)
function isplaceok(a,n,c)
-- 检查前n-1个皇后是否与(n,c)位置冲突
for i = 1, n - 1, 1 do
if a[i] == c or -- 是否同一列
a[i] - i == c - n or --是否同一对角线 (?)
a[i] + i == c + n then --是否同一对角线 (?)
return false
end
end
return true -- 不会被攻击 位置有效
end
-- 用于在找到解后打印棋盘
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
-- 已经找到前n-1皇后的位置
-- 存放于a中
-- 寻找第n个皇后可摆放的位置
function addqueen(a,n)
if n > N then
printsolution(a)
return true
else
-- 逐列检查能否摆放第n个皇后
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c
if addqueen(a, n+1) then
return true
end
end
end
end
end
-- 启动方式
addqueen({}, 1)
书后练习
1. 修改八皇后问题的程序,使其在输出第一个解后即停止运行。
修改addqueen函数即可。
-- 已经找到前n-1皇后的位置
-- 存放于a中
-- 寻找第n个皇后可摆放的位置
function addqueen(a,n)
if n > N then
printsolution(a)
return true
else
-- 逐列检查能否摆放第n个皇后
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c
if addqueen(a, n+1) then
return true
end
end
end
end
end
2. 解决八皇后问题的另一种方式是,先生成1-8之间的所有排列,然后依次遍历这些排列,检查每一个排列是否是八皇后问题的有效解。请使用这种方法修改程序并对比性能差异。
一定是原本的方法效率更高…1-8之间的所有排列一共有8的8次幂个,检查每个排列是否合法又是O(n^2)的复杂度,效率会很低。只看isplaceok函数调用次数的话,原来的方法一共调用isplaceok函数876次,生成所有排列的方法生成了8的8次幂个排列,每个排列调用isplaceok的次数最少1次,最多8次,整体也在5千万次以上。
实际测了一下,用的在线编辑器,直接爆掉了。又重新用本地的lua跑了一下。调用isplaceok的次数为50889536次。(妈呀)
N = 8
--[[
N为棋盘规模
a为一维数组,保存第i个皇后所在的列数
]]
count = 0
-- 检查是否可以将第n个皇后放在第n行第c列(前n-1行的皇后已经放好)
function isplaceok(a,n,c)
count = count + 1
-- 检查前n-1个皇后是否与(n,c)位置冲突
for i = 1, n - 1, 1 do
if a[i] == c or -- 是否同一列
a[i] - i == c - n or --是否同一对角线 (?)
a[i] + i == c + n then --是否同一对角线 (?)
return false
end
end
return true -- 不会被攻击 位置有效
end
-- 用于在找到解后打印棋盘
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
-- 已经放置前n-1皇后
-- 存放于a中
-- 放置第n个皇后
function addqueen(arrays, a, n)
if n > N then
table.insert(arrays, a)
else
-- 逐列检查能否摆放第n个皇后
for c = 1, N do
local b = {}
for k, v in pairs(a) do
b[k] = v
end
b[n] = c
addqueen(arrays, b, n+1)
end
end
end
function getsolution()
local posibles = {}
addqueen(posibles, {}, 1)
for _, v in pairs(posibles) do
local ok = true
for i = 1, N do
ok = isplaceok(v, i, v[i])
if not ok then
break
end
end
if ok then
printsolution(v)
end
end
end
-- 启动方式
getsolution()
io.write("\n",count)
Lua实现的八皇后问题的更多相关文章
- 八皇后算法的另一种实现(c#版本)
八皇后: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于 ...
- 数据结构0103汉诺塔&八皇后
主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...
- Python学习二(生成器和八皇后算法)
看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 ...
- Python解决八皇后问题
最近看Python看得都不用tab键了,哈哈.今天看了一个经典问题--八皇后问题,说实话,以前学C.C++的时候有这个问题,但是当时不爱学,没搞会,后来算法课上又碰到,只是学会了思想,应该是学回溯法的 ...
- OpenJudge1700:八皇后问题 //不属于基本法的基本玩意
1700:八皇后问题//搜索 总时间限制: 10000ms 内存限制: 65536kB 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 输入 无输入. 输出 按给定顺序和 ...
- C#八皇后问题 枚举值
记得刚出道的时候, 有考虑怎么面试, 以及可能会遇到的面试题, 有一个人说了一下 八皇后问题, 据说要用 sql 语句写出来, 暂时我 写了一个C#版本的, 经测验,八皇后算法结果为 92种, 这个与 ...
- 八皇后(dfs+回溯)
重看了一下刘汝佳的白板书,上次写八皇后时并不是很懂,再写一次: 方法1:逐行放置皇后,然后递归: 代码: #include <bits/stdc++.h> #define MAXN 8 # ...
- C语言解决八皇后问题
#include <stdio.h> #include <stdlib.h> /* this code is used to cope with the problem of ...
- 八皇后,回溯与递归(Python实现)
八皇后问题是十九世纪著名的数学家高斯1850年提出 .以下为python语句的八皇后代码,摘自<Python基础教程>,代码相对于其他语言,来得短小且一次性可以打印出92种结果.同时可以扩 ...
随机推荐
- Docker基础内容之数据持久化
数据卷的特性 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS 数据卷可以在容器之间共享和重用,相当于将一个分区挂载到多个目录下面 数据卷内容的修改会立马生效 数据卷的更新,不会影响镜像: ...
- Docker基础内容之容器
前言 容器是独立运行的一个或一组应用以及它们的运行态环境. 相关命令 启动容器相关命令 docker run 运行一个ubuntu14.04版本的容器,如果这个镜像本地不存在则会去默认仓库中下载 do ...
- 【学习笔记】Linux基础(零):预备知识
学习笔记(连载)之Linux系列 Note:本学习笔记源自<鸟哥的Linux私房菜(基础学习篇)>一书,为此书重要内容的摘要和总结,对于一些常识性的知识不再归纳 新型冠状病毒引发的肺炎战& ...
- DWZ框架--页面样式丢失
案例 今天我导入DWZ框架demo时,发现主页面样式丢失,出现了如下图那鬼样: 正常情况应该是有表格显示,并且用chrome开发者模式调试,可以看到有对应的样式,如下图所示: 先简单介绍下dwz框架的 ...
- 低功耗设计技术--Multi VDD--Level shifter
本文转自:自己的微信公众号<集成电路设计及EDA教程> 前面的推文中我们分别介绍了低功耗设计中的Multi-VDD技术以及门控电源技术.在实际的低功耗设计中,门控电源技术中也常常结合Mul ...
- 谷歌翻译API
http://translate.google.cn/translate_a/t?client=t&text=你好&hl=zh-CN&sl=zh-CN&tl=en&am ...
- 认识Git与GitHub
Git介绍 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.相比CVS.SVN等版本控制工具,Git更加优秀,功能也更加强大.但是相对也难学. 使用Git来管理 ...
- C# 接口和继承
转:https://www.cnblogs.com/songhe123/p/9558545.html 接口是方法的抽象,如果不同的类有同样的方法,那么就应该考虑使用接口. 例1: using Syst ...
- Cheat Sheet pyspark RDD(PySpark 速查表)
- [pathlib]内置pathlib库的常用属性和方法
pathlib中的Path类可以创建path路径对象, 属于比os.path更高抽象级别的对象. 官网 from pathlib import Path path = Path(__file__) p ...