算法思路
注意遍历所有情况都顺序
和当发现有解,和提前剪枝时的回溯情况
#include <iostream>
using namespace std;
const int N = 20;
//存放棋谱中*和Q和情况
char g[N][N];
int n;
//bool数组用于表示该 列col 对角线dg 反对角线udg 是否可以继续存储
bool col[N],dg[N],udg[N];
//每行只能放一个皇后,所以用类似全排列的方式搜索
void dfs(int u)
{
//当u表示已经放入的皇后数,当u == n时说明已经将n个皇后放入,求得一解,输出即可。
if(u == n)
{
//等价于cout << g[i] << endl;
for(int i = 0; i<n;i++)
puts(g[i]);
puts("");
return ;
}
//n个位置按行排列,u表示在选第u行的列的位置,遍历列
for(int i = 0; i < n;i ++)
{
//倘若该列,对角线,反对角线均没有皇后则将其放置。
// udg[n - u + i],+n是为了保证下标非负
if(!col[i] && !dg[u+i] && !udg[n-u+i])
{
g[u][i] = 'Q';
//更新放置情况
col[i] = dg[u + i] = udg[n - u + i] = true;
//深一层的选择
dfs(u+1);
//恢复现场
//什么时候恢复现场:比如当在dfs(u+1)时,发现u+1行没有一列有元素放置,则进行剪枝,
//如何恢复:递归回原来的
col[i] = dg[u + i] = udg[n - u + i] = false;
g[u][i] = '.';
}
}
}
int main()
{
cin >> n;
//初始化棋谱
for(int i = 0;i<n;i++)
for(int j = 0;j<n;j++)
g[i][j] = '.';
dfs(0);
return 0;
}