问题描述:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上问有多少种摆法。8皇后是典实际上一个类似枚举的搜索尝试过程,它的的基本思想是在所有的解空间中,先深度搜索求出一种解法不满足约束条件的解时,回退到之前的解,继续对问题求解8皇后也可以推广为一般情形,将棋盘扩展为n*n,此时皇后个数n(n=1或>=4时有解)。
思路:逐行放置,逐列搜索。从当前行的第一列开始搜索,判断该位置是否合法。合法则递归判断下一行,不合法则搜索下一列,直到最后一列也不符合,或者在最后一行放下棋子就返回上一次递归,一直到第一行遍历完毕。
#include<iostream>
#include<cmath>
#include<windows.h>
#define MAXSIZE 8
char a[MAXSIZE][MAXSIZE];
int Totalnumber=0;
using namespace std;
bool isillegal(int row,int col)//判断该位置是否合法(逐行判断故只要判断列和对角线)
{
for(int i=0;i<row;i++)
{
if(a[i][col]=='*') return false;//判断是否在同一列
else continue;
}
for(int i=0;i<row;i++)//判断是否在同一对角线
{
for(int j=0;j<MAXSIZE;j++)
{
if(abs(i-row)==abs(j-col) && a[i][j]=='*') return false;//同一对角线的斜率相同
else continue;
}
}
return true;
}
void print()
{
for(int i=0;i<MAXSIZE;i++)
{
for(int j=0;j<MAXSIZE;j++)
{
cout<<a[i][j]<<' ';
}
cout << '\n';
}
cout << '\n';
}
void solution(int number)//参数为当前行数
{
for(int i=0;i<MAXSIZE;i++)
{
if(isillegal(number,i))
{
a[number][i]='*';
if(number==MAXSIZE-1)
{
Totalnumber++;//满足条件的总数
print();//输出数组
cout << Totalnumber<<'\n';
system("pause");//输出后暂停
}
else solution(number+1);
a[number][i]='#';
}
}
}
void inits()//初始化数组
{
for(int i=0;i<MAXSIZE;i++)
{
for(int j=0;j<MAXSIZE;j++)
{
a[i][j]='#';
}
}
}
int main()
{
inits();
solution(0);
return 0;
}
这是最后的运行结果“*”表示棋子: