n皇后问题
- 位运算版本(返回可能数)
int totalqueen(int n)
{
if(n < 1) return 0;
// n = 5
// 1 << 5 = 0...100000 - 1
// limit = 0...011111;
// n = 7
// limit = 0...01111111;
int limit = (1 << n) - 1;
return f2(limit, 0, 0, 0);
}
// limit : 当前是几皇后问题
// 之前皇后的列影响:col
// 之前皇后的右上 -> 左下对角线影响:left
// 之前皇后的左上 -> 右下对角线影响:right
int f2(int limit, int col, int left, int right)
{
// 所有皇后放完了!
if(col == limit) return 1;
// 总限制
int ban = col | left | right;
// ~ban : 1可放皇后 0不可放皇后
int candidate = limit & (~ban);
// 放置皇后的尝试
int place = 0;
// 一共有多少种有用的方法
while(candidate)
{
// 提取出最右侧的1
// 0 0 1 1 1 0
// 5 4 3 2 1 0
// place :
// 0 0 0 0 1 0
// candidate :
// 0 0 1 1 0 0
// 5 4 3 2 1 0
// place :
// 0 0 0 1 0 0
// candidate :
// 0 0 1 0 0 0
// 5 4 3 2 1 0
// place :
// 0 0 1 0 0 0
// candidate :
// 0 0 0 0 0 0
// 5 4 3 2 1 0
place = candidate & (-candidate);
// 更新可放置位置
candidate ^= place;
ans += f2(limit, col | place, (left | place) >> 1, (right | place) << 1);
}
return ans;
}
- 返回路径
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
char path[N][N];
bitset<2 * N> a, b;
bitset<N> c;
int n;
void dfs(int u)
{
if(u == n + 1)
{
for(int i = 1; i <= n; i ++ )
{
for(int j = 1; j <= n; j ++ ) cout << path[i][j];
cout << endl;
}
cout << endl;
return;
}
for(int i = 1; i <= n; i ++ )
{
if(!c[i] && !a[u + i] && !b[i - u + n])
{
path[u][i] = 'Q';
c[i] = a[u + i] = b[i - u + n] = 1;
dfs(u + 1);
c[i] = a[u + i] = b[i - u + n] = 0;
path[u][i] = '.';
}
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= n; j ++ )
path[i][j] = '.';
dfs(1);
return 0;
}
标签:right,candidate,int,limit,问题,place,皇后
From: https://www.cnblogs.com/hnu-hua/p/18179452