简单的搜索——N皇后问题
题目
在一张N∗N的国际象棋棋盘上,放置N个皇后,使得所有皇后都无法互相直接攻击得到,(皇后可以直接攻击到她所在的横行,竖列,斜方向上的棋子),现在输入一个整数N,表示在N∗N的棋盘上放N个皇后,请输出共有多少种使得所有皇后都无法互相直接攻击得到的方案数。 例如下面这样的摆法,是4皇后的一个解 (1代表有皇后,0代表没有)
0 1 0 0
0 0 0 1
1 0 0 0
0 0 1 0
输入
一个整数N
输出
能使得在N∗N的国际象棋棋盘上放置N个皇后,并且所有皇后都无法互相直接攻击得到的方案数
样例输入
样例输入1
4
样例输入2
8
样例输出
样例输出1
2
样例输出2
92
做题思路
1.对于这道题由于一行只有一个皇后所以可以使用一个以为数组存储皇后的位置,下标是行数,里面存储皇后所在列数。
2.直接DFS暴力搜索,从第一行第一列开始放入皇后,确定之后对于以后每一行放入的皇后应该满足一下两个条件。
1).新放入皇后与之前旧皇后的行数与列数之差的绝对值相等。
2).由于每行一个皇后确定只需比较列数是否重复。
两者满足一个说明这一列不能放入新皇后。
3.递归return的条件
1).到了最后一行。
2).某一行没有列可以放入皇后。
代码
//N皇后问题
#include<cstdio>
#include<iostream>
#include<cstdlib>
using namespace std;
int map[20];//存放皇后的位置
int ans=0;//记录有多少中情况
int m;//皇后总数
int dfs(int n) {
int i, j;
for (i = 1; i <= m; i++) {
int temp = 0;
for (j = n - 1; j > 0; j--) //与之前的放的皇后一一比较
{
if (abs(i - map[j]) == abs(j - n) || i == map[j]) {
temp = 1;//标记,说明这一行不能放皇后
break;
}
}
if (temp == 0) {
map[n] = i;//标记这一行皇后的列数
if (n == m) {
ans++;
return 0;
}
dfs(n + 1);
map[n] = 0;//退出标记
}
}
if (i > m) {
return 0;
}
}
int main()
{
scanf("%d",&m);
dfs(1);
printf("%d",ans);
return 0;
}