码迷,mamicode.com
首页 > 其他好文 > 详细

N皇后问题(位运算实现)

时间:2014-08-17 22:45:32      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   ar   

本文参考Matrix67的位运算相关的博文。

顺道列出Matrix67的位运算及其使用技巧 (一) (二) (三) (四),很不错的文章,非常值得一看。

 

    主要就其中的N皇后问题,给出C++位运算实现版本以及注释分析。

    皇后问题很经典,就不再赘述问题本身,解决皇后问题,一般采用的都是深搜DFS+回溯的方法,按照行(列)的顺序枚举每一个可以放置的情况,然后进行冲突判断,当前的放置是否合法,合法就继续搜索下一层,不合法就搜索就回溯。直到,找到一个合法的解,每一层都有一个皇后并且不发生冲突,这时候,放置的方案数计1.

    位运算也是采用的也是深搜加回溯的方法,但是优点在于使用位运算进行冲突的检测,这使代码简洁高效,而且还加快了运行速度。

    下面的两张图来自Matrix67的(三):

bubuko.com,布布扣                                            bubuko.com,布布扣

    depth 表示当前要进行搜索的层,row的二进制表示当前层二进制为1是冲突列,ld表示从右上角到左下角对角线冲突关系,rd表示的从左上角到右下角的冲突关系。

    具体实现代码如下:

#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

const int N = 16; // 求解N皇后, N不能超过int的bits
int upper_limit = (1 << N) - 1; // 111...1111 n bits
int ans = 0;

void test(int row, int ld, int rd) {
    // 如果row的皇后还没有放满
    if (row != upper_limit) {
        // (row|ld|rd)表示行row,右上到左下ld,左上到右下rd对角线,为1则是不能放的位置, 取~后表示能放置的位置
        // 因为是用的int 32位存的,所以N位向上的高位需要重新置成0
        // 所以再和upper_limit取&操作,就提取出所有可以放置皇后的位置
        int pos = upper_limit & ~(row | ld | rd);
        
        // while 循环枚举所有为1的位置,然后去放置皇后
        while (pos != 0) {
            // 和树状数组的lowbit一样,提取出pos的二进制最后一个1所在的位置的值
            // 也可以写成x & (x^(x-1))
            int p = pos & (-pos);  
            
            pos = pos ^ p; // 将p二进制为1的位置在pos中置为0
            // row | p 把p二进制为1的位置放上皇后
            // (ld | p) << 1 更新ld的下一层不能放的位置
            // (rd | p) >> 1 更新rd的下一层不能放的位置
            test(row|p, (ld|p) << 1, (rd|p) >> 1);
        }
    } else ans++;

}

int main() {
    ans = 0;
    clock_t start, finish;
    double duration;
    start = clock();
    test(0, 0, 0);
    finish = clock();
    duration = (double)(finish-start) / CLOCKS_PER_SEC;
    printf("Time is %lf\n", duration); 
    printf("共有多少种情况: %d\n", ans);
    return 0;
}

分析:

位运算版本确实在代码编写和时间效率上都相当棒

代码的关键部分,就在于处理row,ld,rd搜索时候的禁位变化

当处理超过int可表示位数时候,这时候就要抛弃整型,使用bitset或者位结构去做相关操作

 

N皇后问题(位运算实现),布布扣,bubuko.com

N皇后问题(位运算实现)

标签:style   blog   http   color   使用   os   io   ar   

原文地址:http://www.cnblogs.com/tiny656/p/3918367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!