n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
现在给定整数 n,请你输出所有的满足条件的棋子摆法。
输入格式
共一行,包含整数 n。
输出格式
每个解决方案占 n行,每行输出一个长度为 n的字符串,用来表示完整的棋盘状态。
其中 .
表示某一个位置的方格状态为空,Q
表示某一个位置的方格上摆着皇后。
每个方案输出完成后,输出一个空行。
注意:行末不能有多余空格。
输出方案的顺序任意,只要不重复且没有遗漏即可。
数据范围
1≤n≤9
输入样例:
4
输出样例:
.Q..
...Q
Q...
..Q...Q.
Q...
...Q
.Q..
解题思路:
每次遍历每个格子,有两种选择放Q,不放Q。
如果放Q需要检查当前行,列,对角线,反对角线是否已被标记过。
对角线与反对角线表示:由于直线方程(斜率正负)有两种表达:y=x+b,y=-x+b;
正好对应着对角线与反对角线,不过在途中x为行,y为列需要互换一下。
参考代码:
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;
const int N = 10;
char g[N][N];
bool row[N],col[N],dg[N],udg[N];//行,列,正对角线(x+y),反对角线(n-y+x)
bool st[N];
int n;void dfs(int u,int x,int y)
{if(u>n) return;if(y==n) y = 0,x++;if(x==n){if(u==n){for(int i=0;i<n;i++) puts(g[i]);puts(" ");}return;}g[x][y] = '.';dfs(u,x,y+1);if(!row[x] && !col[y] && !dg[x+y] && !udg[n-y+x]){g[x][y] = 'Q';row[x] = col[y] = dg[x+y] = udg[n-y+x] = true;dfs(u+1,x,y+1);g[x][y] = '.';row[x] = col[y] = dg[x+y] = udg[n-y+x] = false;}
}int main()
{cin>>n;dfs(0,0,0);return 0;
}