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

图论 - 图的遍历 - 深度优先搜索 - n皇后问题

时间:2019-03-24 17:38:59      阅读:219      评论:0      收藏:0      [点我收藏+]

标签:测试   stream   取反   answer   搜索   一个   ble   方案   位置   

n皇后问题

描述

n皇后问题:一个n×n的棋盘,在棋盘上摆n个皇后,满足任意两个皇后不能在同一行、同一列或同一斜线上的方案有多少种?

输入

第一行包含一个整数n。

输出

输出一个整数,表示方案数。

样例输入

4

样例输出

2

限制

一共10个测试点, 第i个测试点的n=i+4。

时间:2 sec

空间:512 MB

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

C++代码

#include <iostream>
using namespace std;

int ans, allOne;    // ans:答案;allOne:用于二进制&的全1数。


/* 深度优先搜索(用二进制优化)获得合法的皇后摆放位置。
   pos:其二进制上的某个位置的1表示当前所在行的相应的位置(列)已经放了一个皇后。
   left:其二进制上的某个位置的1表示当前所在行的相应的位置(是由于右对角线上已有皇后)不能放置皇后。
   right:其二进制上的某个位置的1表示当前所在行的相应位置(是由于左对角线上已有皇后)不能放置皇后。
*/
void dfs(int pos, int left, int right)
{
    /* 当且仅当每一列都放了一个皇后那么整个棋盘已经放了n个合法皇后,故要终止 */
    if ( pos == allOne )
    {
        ++ans;     // 到了此步,证明已经得到了一个合法的方案。
        return;
    }
    
    /* can_put为1的位表示能放皇后。用掩码保证can_put除了低n位以外的更高位均为0,因为取反和下面循环中的左移可能使除低n位外的更高位出现1. */
    int can_put = allOne & ( ~(pos | left | right) );
    
    /* 对于can_put每个为1的位,放置一个皇后,更新pos, left, right,然后继续下一步搜索。 */
    while ( can_put )    // 只要put不为0,证明它还有为1的位,还有可能放皇后的位置
    {
        int put = can_put & -can_put;    // 这样运算,put只有can_put的最低位为1的位置为1,其他位置均为0。
        dfs(pos|put, (left|put)<<1, (right|put)>>1);
        can_put ^= put;    // 一个二进制位与1异或把该位取反,与0异或该位不变,故该语句把此次放置皇后的位置在can_put中置0(因为这个位置放置皇后的情况已经在此次循环中计算完了)。
    }
    
}


/* 一个n×n的棋盘,在棋盘上摆n个皇后,求满足任意两个皇后不能在同一行、同一列或同一斜线上的方案数。
   n:上述n
   返回值:方案数
*/
int getAnswer(int n) 
{
    ans = 0;
    allOne = (1 << n) - 1;    // 得到一个低n位均为1,其他位为0的二进制。
    dfs(0, 0, 0);    // 开始棋盘上没有棋子,故pos、left、right的各位均为0。 
    return ans;
}


int main()
{
    int n;
    cin >> n;
    cout << getAnswer(n) << endl;
    return 0;
}

 

图论 - 图的遍历 - 深度优先搜索 - n皇后问题

标签:测试   stream   取反   answer   搜索   一个   ble   方案   位置   

原文地址:https://www.cnblogs.com/fyqq0403/p/10588940.html

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