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

  • 相关阅读:
    远程桌面连接偶尔无法连接的解决方案
    事物复制遇到的几个错误
    几条关于查看和删除发布和分发的命令
    Winform- TreeView的使用例子
    Winform- 界面开发之布局控件"WeifenLuo.WinFormsUI.Docking"的使用
    Winform- IrisSkin.dll轻松实现窗体换肤功能
    Oracle- 备份单表结构和单表数据
    MSSQLSERVER数据库- 作业调度定时备份数据库
    Oracle- plsql developer如何查询SQL语句执行历史记录
    MSSQLSERVER数据库- SQL删除重复数据的五种方式
  • 原文地址:https://www.cnblogs.com/ftae/p/7001043.html
Copyright © 2011-2022 走看看