皇后问题:在一个由N2个方块排成N行N列的正方形,称为N元棋盘,在N元棋盘上放置N个皇后,如果某两个皇后位于N元棋盘的同一行或同一列或同一斜线(斜率为±1)上,则称它们在互相攻击,试设计算法找出使N个皇后互不攻击的所有布局。
在这个问题当中我们需要的是求出所有的组合情况我们需要采用回溯的方法。
首先我们设置好棋盘,然后我们在设置行,列,对角线和反对角线的值。
然后我们进行判断当我们放置的数量已经超过N的时候就退出,当我们搜索完所有的列的时候我们就退回到第一列并且行数加一也就是搜索完本行所有列后就去下一行的第一列开始搜索。当我们发现正好搜索到最后一行并且也正好放了n个皇后我们就可以输出结果了。
这个过程是利用行列对角线反对角线的值来进行判断的只有他们都为false表示他们都是安全的不会发生攻击的是可以放皇后的。然后就可以放置皇后并且再将他们的值设为true然后进行向下一列进行寻找去放置。
#include <stdio.h>
const int N = 20; //设置最多20元棋盘
char m[N][N]; //棋盘
int n; //n元棋盘
bool row[N], col[N], dj[N], udj[N]; //行,列,对角线,反对角线
void dfs(int x, int y, int s)
{
if (s > n) return ;
if (y == n) y = 0, x ++;
if (x == n)
{
if (s == n)
{
for(int i = 0; i < n; i++) puts(m[i]);
puts("");
}
return ;
}
//不放
dfs(x, y + 1, s);
//放
if (!row[x] && !col[y] && !dj[x + y] && !udj[n + x - y])
{
m[x][y] = 'Q';
row[x] = col[y] = dj[x + y] = udj[n + x - y] = true;
dfs(x, y + 1, s + 1);
row[x] = col[y] = dj[x + y] = udj[n + x - y] = false;
m[x][y] = '.';
}
}
int main()
{
printf("请输入是几元棋盘:\n");
scanf("%d",&n);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
m[i][j] = '.'; //画棋盘
dfs(0, 0, 0); //从棋盘起点开始出发
return 0;
}