zoukankan      html  css  js  c++  java
  • N皇后问题(C++实现和函数式编程实现)

    题意

    在 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 函数过滤掉存在冲突的格局。

  • 相关阅读:
    事例学习开发WEBSERVER服务器(一)
    一个简单的减法程序看看基本功
    Linux 网络编程一步一步学(三)循环读取服务器上的数据
    screen配置——screenrc
    ubuntu NGINX LUA安装
    Linux 网络编程一步一步学(二)绑定IP 和端口
    git常用命令
    浅谈算法——冒泡排序
    ack 安装和使用事例
    Linux 网络编程一步一步学(六)客户/服务端通信
  • 原文地址:https://www.cnblogs.com/ftae/p/7001043.html
Copyright © 2011-2022 走看看