题意

在 N * N 的方格棋盘放置了 N 个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。求出有多少种合法的放置方法。

C++实现(位运算优化)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int MAX, ans;
void dfs(int row, int ld, int rd) {
if(row == MAX) {
ans++;
return;
}
int pos = (MAX & ~(row | ld | rd));
while(pos) {
int p = (pos & -pos); // 找到二进制位最低位的 1 的位置
dfs(row | p, (ld | p) << 1, (rd | p) >> 1);
pos -= p;
}
}
int main() {
while(cin >> n && n) {
if(n == 1) cout << 1 << endl;
else if(n < 4) cout << 0 << endl;
else {
ans = 0;
MAX = (1 << n) - 1;
dfs(0, 0, 0);
cout << ans << endl;
}
}
return 0;
}

scheme实现

用的 r5rs 版本,所以许多函数需要自己定义。

(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence))))) (define (enumerate-interval low high)
(if (> low high)
nil
(cons low (enumerate-interval (+ low 1) high)))) (define (flatmap proc seq)
(accumulate append nil (map proc seq))) (define (filter f? seq)
(define (iter result seq)
(cond ((null? seq) result)
((f? (car seq)) (iter (cons (car seq) result) (cdr seq)))
(else (iter result (cdr seq)))))
(iter '() seq)) (define (queens board-size)
(define empty-board '())
(define (safe? k positions)
(define (iter-check row-of-new-queen rest-of-queens i)
(if (= i k)
#t
(let ((row-of-current-queen (car rest-of-queens)))
(if (or (= row-of-new-queen row-of-current-queen)
(= row-of-new-queen (+ row-of-current-queen i))
(= row-of-new-queen (- row-of-current-queen i)))
#f
(iter-check row-of-new-queen
(cdr rest-of-queens )
(+ i 1))))))
(iter-check (car positions) (cdr positions) 1))
(define (adjoin-position new-row rest-of-queens)
(cons new-row rest-of-queens))
(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 rest-of-queens))
(enumerate-interval 1 board-size)))
(queen-cols (- k 1))))))
(queen-cols board-size)) (define (count l)
(if (null? l)
0
(+ (count (cdr l)) 1))) (count (queens 8))

flatmap 函数把产生的新皇后的位置加入到每个已经符合条件的格局(已经摆放好的皇后的状态)中,这里 rest-of-queens 是在前 k - 1 列放置 k - 1 个皇后的一种方式,使用 map 函数映射 [1, n],adjoin-position 函数的作用就是把 [1, n] 的值当作新皇后的行的位置加入到某一个格局中,用 filter 函数过滤掉存在冲突的格局。

N皇后问题(C++实现和函数式编程实现)的更多相关文章

  1. angular2系列教程(六)两种pipe:函数式编程与面向对象编程

    今天,我们要讲的是angualr2的pipe这个知识点. 例子

  2. [学习笔记]JavaScript之函数式编程

    欢迎指导与讨论:) 前言 函数式编程能使我们的代码结构变得简洁,让代码更接近于自然语言,易于理解. 一.减少不必要的函数嵌套代码 (1)当存在函数嵌套时,若内层函数的参数与外层函数的参数一致时,可以这 ...

  3. 函数式编程之柯里化(curry)

    函数式编程curry的概念: 只传递给函数一部分参数来调用函数,然后返回一个函数去处理剩下的参数. var add = function(x) { return function(y) { retur ...

  4. 关于Java8函数式编程你需要了解的几点

    函数式编程与面向对象的设计方法在思路和手段上都各有千秋,在这里,我将简要介绍一下函数式编程与面向对象相比的一些特点和差异. 函数作为一等公民 在理解函数作为一等公民这句话时,让我们先来看一下一种非常常 ...

  5. Haskell 函数式编程快速入门【草】

    什么是函数式编程 用常规编程语言中的函数指针.委托和Lambda表达式等概念来帮助理解(其实函数式编程就是Lambda演算延伸而来的编程范式). 函数式编程中函数可以被非常容易的定义和传递. Hask ...

  6. java1.8函数式编程概念

    有关函数式编程 ·1 函数作为一等公民 特点:将函数作为参数传递给另外一个函数:函数可以作为另外一个函数的返回值 ·2 无副作用 函数的副作用指的是函数在调用过程中,除了给出了返回值外,还修改了函数外 ...

  7. 让JavaScript回归函数式编程的本质

    JavaScript是一门被误会最深的语言,这话一点不假,我们看下它的发展历史. 1995年,Netscape要推向市场,需要一门脚本语言来配套它.是使用一门已有的语言,还是发明一门新的语言,这也不是 ...

  8. python基础-函数式编程

    python基础-函数式编程  高阶函数:map , reduce ,filter,sorted 匿名函数:  lambda  1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层 ...

  9. python函数 与 函数式编程

    「函数」一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,具体区别,我们后面会讲,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序), ...

  10. Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程

    Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程 这里的函数式编程的设计以muduo为例进行对比说明: Reactor实现架构对比 面向对象的设计类图如下: 函数式编程以muduo为例 ...

随机推荐

  1. Jforum环境之Tomcat环境搭建

    Jforum环境搭建,需先安装JDK.JRE.Tomcat.Mysql(JDK.JRE暂不做说明).本文先说Tomcat环境搭建 1.进入Apache Tomcat官网下载,我选择的是免安装的zip包 ...

  2. vue零碎收集

    在组件中创建dom: let a=document.querySelector('.test'); let newDom=document.createElement("div") ...

  3. 关于 vee-validate直接引用的方法

    转载于:https://blog.csdn.net/hy111/article/details/79046500?%3E 由于当前项目使用的是基于jQuery的前端结构,尝试在新增需求中使用VUE2, ...

  4. hexo站点地图

    将网站链接提交到百度 百度搜索引擎提交入口 有三种验证方式,我选择Html标签验证,在themes\next\layout\_partials\head.swing中添加验证代码: <meta ...

  5. 【Python】- pytharm 中import时无法识别自己写的程序

    右键点击自己的工作空间,找下面的Mark Directory as(将目录标记为) 选择Source Root,就可以解决上面的问题了,如图

  6. CentOS Linux上搭建PPPoE服务器及拨号设置

    CentOS Linux上搭建PPPoE服务器及拨号设置 搭建PPPoE,成功了的话,就觉得超级简单,在CentOS Linux更是5步左右就能搞定. 1.安装pppoe,安装完成后,会有pppoe- ...

  7. JS DOM对象与jQuery对象的转换

    JS转jQuery // 直接用$()来包裹 如同$(this) $(document) var jsObj = document.getElementById('test'); var jquery ...

  8. 《c程序设计语言》读书笔记-5.8-天数和日期转换错误检查

    #include "stdio.h" #include "stdlib.h" #include "string.h" static char ...

  9. Debian中文字体安装

    默认装的英文办的debian7,看中国字不太美,这好办照着做吧 1. Setup locales #dpkg-reconfigure locales 选择 zh_CN GB2312 zh_CN.GBK ...

  10. HDU1541 经典树状数组

    HDU1541 题意: 如图,等级为0的点有1,等级为1得点有4,2  等级为2的点有3,等级为3的点有5-------即即左下角的点的个数 现给你一些点(x,y),输入顺序按y升序,y相等时按x升序 ...