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

  • 相关阅读:
    HTML5简介
    C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)
    C#结构体和字节数组的转换
    UML学习站点推荐
    C#面向对象设计模式纵横谈(1):面向对象设计模式与原则
    将WinCE5.0模拟器连接到VS2005[转]
    【转】转载:想学英语的好好留着!
    asp.net页面编码问题
    SQL Server 2005 Compact Edition移动开发指南[转]
    小议Windows CE 的下浏览器配置[转]
  • 原文地址:https://www.cnblogs.com/ftae/p/7001043.html
Copyright © 2011-2022 走看看