EOJ 1130 8皇后问题(回溯)

题目描述

利用回溯法计算 n*n 棋盘中摆放 n 个皇后的方案数

输入格式

第一行有一个整数 k,表示有 k 个 case,

接下来 2..k+1 行,每行有一个整数,表示 n*n 的棋盘 (0 < n <= 8)。

输出格式

输出共有 k 行

每行有一个整数,即 n*n 的摆放皇后的方案数

样例

input

2
8
8

output

92
92

思路:网上找到了另一种回溯法,用二进制位来记录当前行可以走的格子,并可以推导出下一行可以走的格子。基本思想是:用col、m_diag、c_diag三个变量的最低n位记录当前行的列、主对角线、副对角线占用情况,1表示被占用,0表示可以走,三个变量或运算的结果是这行可以走的格子情况,并以此递推出下一行可用的格子。如果皇后太多的话,int类型的位数可能不够用,可以考虑使用bitset替代。具体代码如下:

#include 

using namespace std;

int lim, ans;

void queen(int col, int m_diag, int c_diag)//col,m_diag,c_diag每一位的1表示被占用,0表示可走
{
    if(col == lim){//所有列都走完了
        ++ans;
        return;
    }
    int pos = lim & ~(col | m_diag | c_diag);//求得所有可走的格子并用1表示
    while(pos){//当前行仍有格子可以走
        int cur = pos & (~pos + 1);//提取最低位的1(最右边可走的格子)
        pos -= cur;//更新该格子为被占用
        queen(col+cur, (m_diag+cur)>>1, (c_diag+cur)<<1);//递推下一行的占用情况
    }
}


int main()
{
    int k, n;
    cin>>k;
    for(int cas=0; cas>n;
        ans = 0;
        lim = 1;
        lim = (lim<

 

你可能感兴趣的:(EOJ)