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

Posted fyqq0403

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图论 - 图的遍历 - 深度优先搜索 - n皇后问题相关的知识,希望对你有一定的参考价值。

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皇后问题的主要内容,如果未能解决你的问题,请参考以下文章

Java 深度遍历和广度优先遍历

Java 深度遍历和广度优先遍历

基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

深度优先搜索算法解释下?

networkx图论Depth First Search深度优先搜索遍历DFS,基于递归,Python

SDUT-2107_图的深度遍历