《sicp》八皇后谜题
《sicp》八皇后谜题
书中练习2.42.八皇后谜题问的是如何将八个皇后摆在国际象棋棋盘上,使得任意一个皇后都不能攻击另一个皇后(也就是说任意两个皇后都不能在同一行,同一列和同一对角线上).
解题思想
递归加模块化设计程序
递归:解决这一谜题,可以使用递归的方法,每次在一列中放置一个皇后.
- 1.已经放置好了前k-1列的所有皇后.
- 2.第k列处理方法:
- 1.将第k列的每一行都放置一个皇后.
- 2.将第k列不满足条件的皇后过滤掉.
数据结构
每一个具体的解法用列表表示.列表的第一个元素表示第 8 列的皇后所在的行,而列表的第二个元素表示第 7 列的皇后所在的行,以此类推。
例如
可以表示为 (list 6 3 1 7 5 8 2 4) 。
所有解法综合起来采用二维列表表示.(list (list 6 3 1 7 5 8 2 4) (list ...) (list ...) ...).
列表内的每一个列表都代表一个具体的解法.
scheme程序
程序框架
(define (queens board-size)
(define (queen-cols k)
(if (= k 0)
(list empty-board)
(filter
(lambda (positions) (safe? k positions))
(flatmap
(lambda (rest-of-queens)
(map (lambda (new-row)
(adjoin-position new-row k rest-of-queens))
(enumerate-interval 1 board-size)))
(queen-cols (- k 1))))))
(queen-cols board-size))
其中:
queen-cols返回在棋盘前k列放置皇后的所有格局的序列
filter是过滤掉不符合条件的解法
flatmap是在前k-1列已放好的格局中,将第k列的每一个行中放入一个皇后
rest-of-queens是在前k-1列放置k-1个皇后的一种方式
过滤方式
前k-1列已经放置好,所以只需检验第k行是否满足.
从第k-1行开始,一行一行的检验三个条件,假设第i列的皇后放置位置为(i,y1),第k列的皇后放置为(k,y2)
1.不在同一列,这个肯定满足,无需检验
2.不在同一行,取出当前列的放置行数和第k列的放置行数相比,看是否相等,即y1 =? y2
3.不在同一对角线上,分为两种情况,1:对角线斜率为1,做出过(i,y1)的斜率为1的直线,看与直线x=k,交点是否为(k,y2),如是,则不满足条件,2:斜率为-1,同上
总程序
(define (filter predicate sequence)
(cond ((null? sequence) '())
((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence))))
(else (filter predicate (cdr sequence)))))
(define ( accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence) (accumulate op initial (cdr sequence)))))
(define (flatmap proc seq)
(accumulate append '() (map proc seq)))
(define (enumerate-interval low high)
(if (> low high)
'()
(cons low (enumerate-interval (+ low 1) high))))
(define empty-board '())
(define (safe? k positions)
(define (noconflict? pk x list)
(cond ((= x 0 ) #t)
((or (= pk (car list)) (= pk ( + k (- (car list) x))) (= pk ( - ( + (car list) x) k ))) #f)
(else (noconflict? pk (- x 1) (cdr list)))))
(noconflict? (car positions) (- k 1) (cdr positions)))
(define (adjoin-position new-row k rest-of-queens)
(cons new-row rest-of-queens))
(define (queens board-size)
(define (queen-cols k)
(if (= k 0)
(list empty-board)
(filter
(lambda (positions) (safe? k positions))
(flatmap
(lambda (rest-of-queens)
(map (lambda (new-row)
(adjoin-position new-row k rest-of-queens))
(enumerate-interval 1 board-size)))
(queen-cols (- k 1))))))
(queen-cols board-size))
结果
1 ]=> (for-each (lambda (pos)
(begin
(display pos)
(newline)))
(queens 8))
(4 2 7 3 6 8 5 1)
(5 2 4 7 3 8 6 1)
(3 5 2 8 6 4 7 1)
(3 6 4 2 8 5 7 1)
(5 7 1 3 8 6 4 2)
(4 6 8 3 1 7 5 2)
(3 6 8 1 4 7 5 2)
(5 3 8 4 7 1 6 2)
(5 7 4 1 3 8 6 2)
(4 1 5 8 6 3 7 2)
(3 6 4 1 8 5 7 2)
(4 7 5 3 1 6 8 2)
(6 4 2 8 5 7 1 3)
(6 4 7 1 8 2 5 3)
(1 7 4 6 8 2 5 3)
(6 8 2 4 1 7 5 3)
(6 2 7 1 4 8 5 3)
(4 7 1 8 5 2 6 3)
(5 8 4 1 7 2 6 3)
(4 8 1 5 7 2 6 3)
(2 7 5 8 1 4 6 3)
(1 7 5 8 2 4 6 3)
(2 5 7 4 1 8 6 3)
(4 2 7 5 1 8 6 3)
(5 7 1 4 2 8 6 3)
(6 4 1 5 8 2 7 3)
(5 1 4 6 8 2 7 3)
(5 2 6 1 7 4 8 3)
(6 3 7 2 8 5 1 4)
(2 7 3 6 8 5 1 4)
(7 3 1 6 8 5 2 4)
(5 1 8 6 3 7 2 4)
(1 5 8 6 3 7 2 4)
(3 6 8 1 5 7 2 4)
(6 3 1 7 5 8 2 4)
(7 5 3 1 6 8 2 4)
(7 3 8 2 5 1 6 4)
(5 3 1 7 2 8 6 4)
(2 5 7 1 3 8 6 4)
(3 6 2 5 8 1 7 4)
(6 1 5 2 8 3 7 4)
(8 3 1 6 2 5 7 4)
(2 8 6 1 3 5 7 4)
(5 7 2 6 3 1 8 4)
(3 6 2 7 5 1 8 4)
(6 2 7 1 3 5 8 4)
(3 7 2 8 6 4 1 5)
(6 3 7 2 4 8 1 5)
(4 2 7 3 6 8 1 5)
(7 1 3 8 6 4 2 5)
(1 6 8 3 7 4 2 5)
(3 8 4 7 1 6 2 5)
(6 3 7 4 1 8 2 5)
(7 4 2 8 6 1 3 5)
(4 6 8 2 7 1 3 5)
(2 6 1 7 4 8 3 5)
(2 4 6 8 3 1 7 5)
(3 6 8 2 4 1 7 5)
(6 3 1 8 4 2 7 5)
(8 4 1 3 6 2 7 5)
(4 8 1 3 6 2 7 5)
(2 6 8 3 1 4 7 5)
(7 2 6 3 1 4 8 5)
(3 6 2 7 1 4 8 5)
(4 7 3 8 2 5 1 6)
(4 8 5 3 1 7 2 6)
(3 5 8 4 1 7 2 6)
(4 2 8 5 7 1 3 6)
(5 7 2 4 8 1 3 6)
(7 4 2 5 8 1 3 6)
(8 2 4 1 7 5 3 6)
(7 2 4 1 8 5 3 6)
(5 1 8 4 2 7 3 6)
(4 1 5 8 2 7 3 6)
(5 2 8 1 4 7 3 6)
(3 7 2 8 5 1 4 6)
(3 1 7 5 8 2 4 6)
(8 2 5 3 1 7 4 6)
(3 5 2 8 1 7 4 6)
(3 5 7 1 4 2 8 6)
(5 2 4 6 8 3 1 7)
(6 3 5 8 1 4 2 7)
(5 8 4 1 3 6 2 7)
(4 2 5 8 6 1 3 7)
(4 6 1 5 2 8 3 7)
(6 3 1 8 5 2 4 7)
(5 3 1 6 8 2 4 7)
(4 2 8 6 1 3 5 7)
(6 3 5 7 1 4 2 8)
(6 4 7 1 3 5 2 8)
(4 7 5 2 6 1 3 8)
(5 7 2 6 3 1 4 8)
《sicp》八皇后谜题的更多相关文章
- 算法——八皇后问题(eight queen puzzle)之回溯法求解
八皇后谜题是经典的一个问题,其解法一共有种! 其定义: 首先定义一个8*8的棋盘 我们有八个皇后在手里,目的是把八个都放在棋盘中 位于皇后的水平和垂直方向的棋格不能有其他皇后 位于皇后的斜对角线上的棋 ...
- 递归的神奇之处在于你会发现问题竟然解决了--解N皇后谜题有感
看sicp看到8皇后谜题, 突然兴致来了,尝试独立解决(scheme代码的好处在于,即使你瞟了眼答案, 也不会有任何收获, 除了知道那儿有一坨神秘的括号和英文字符外但Python代码就不同了),成功了 ...
- 八皇后算法的另一种实现(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 # ...
随机推荐
- iOS 10.0前的Notification推送
前言 推送为远程推送,一般由苹果APNS服务器发送给苹果设备(iPhone,iPad) 推送分在前台和后台.在前台时 用户可以在application 的代理回调接口中做相应处理:在后台时 系统会全权 ...
- 使用OpenLiveWriter来写博客
话不多说,首先是下载http://openlivewriter.org/,安装. 博客配置,我是使用博客园,配置如下: 确保博客园自己后台账号"设置"中的"推荐客户端&q ...
- 交易开拓者旗舰版(TB旗舰版)软件升级中如何迁移用户数据
方法一: 1.导出工作区,桌面和系统设置.操作:文件->导入和导出 2.导出公式.操作:tb公式->公式导入导出. 3.拷贝工作室文件.目录在:user\tb用户名\Workroom 4. ...
- javascript_16-对象字面量
JSON与对象字面量相似,仅仅是属性需要使用双引号引号引起. json是描述数据的一种规范 什么是JSON JavaScript Object Notation (JavaScript 对象表示形式) ...
- Spring中抛出异常时,既要要返回错误信息,还要做事务回滚
情况一:如果没有在程序中手动捕获异常,如下代码事务会回滚 情况二:如果在程序中自已捕获异常未往外抛,如下代码事务不会回滚 如果doDbStuff2()这个操作数据库的方法抛出异常,因为将异常捕获未往外 ...
- Python爬虫的三种数据解析方式
数据解析方式 - 正则 - xpath - bs4 数据解析的原理: 标签的定位 提取标签中存储的文本数据或者标签属性中存储的数据 正则 # 正则表达式 单字符: . : 除换行以外所有字符 [] : ...
- shell文件比较运算符
1.文件比较运算符 -e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ] -d filename 如果 filename 为目录,则为真 [ -d ...
- PHP SplQueue 实现队列
$que = new SplQueue(); $que->enqueue("a");//入队列 $que->enqueue("b"); $que-& ...
- CentOS7使用阿里yum源安装Docker
yum install -y yum-utils device-mapper-persistent-data lvm2安装所需的包 # yum-config-manager --add-repo ht ...
- Ajax -异步请求 -jquery中ajax分类 -第一层 $.ajax -第二层($.get /$.post) -第三层($.getJson/$.getScript) -相应演示
Ajax 1.标准请求响应时浏览器的动作(同步操作) 1.1浏览器请求什么资源,跟随显示什么资源2.ajax:异步请求. 2.1局部刷新,通过异步请求,请求到服务器资源数据后,通过脚本修改页面中部分内 ...