从中总结出n皇后求解的规则:
①用数组q[]存放皇后的位置,q[k]表示第k个皇后放置的位置,n皇后问题的一个解是: q[1],q[2],…,q[n],数组q的下标0元素不用。
②先放置第1个皇后,然后依2、3、…、n的次序放置其他皇后,当第n个皇后放置好后产生一个解。为了找所有解,此时算法还不能结束,继续试探第n个皇后的下一个位置。
③第k(k<n)个皇后放置后,接着放置第k+1个皇后,在试探第k+1个皇后的位置时,都是从第1列开始的。
④当第k个皇后试探了所有列都不能放置时,则回溯到第k-1个皇后,此时与第k-1个皇后的位置q[k-1]有关,如果第k-1个皇后的列号小于n即q[k-1]<n,则将其移到下一列,继续试探;否则再回溯到第k-2个皇后,依此类推。
⑤若第1个皇后的所有位置回溯完毕,则算法结束。
⑥放置第k个皇后应与前面已经放置的k-1个皇后不发生冲突。
#include<iostream>
#include<cmath>
#define true 1
#define false 0
#define MAXN 100
using namespace std;
void queens(int t);//t表示第t个皇后
void print_result();//打印出n皇后的位置
int check_place(int k,int col);//检查t皇后放到位置col是否合理
int num;//解决num皇后问题
int sum=0;//记录解决方案的个数
int q[MAXN];//记录t皇后的位置
int main()
{
cin>>num;
queens(1);//从第一个皇后开始
return 0;
}
void queens(int t)
{
if(t>num){
sum++;
cout<<"方案"<<sum<<':'<<endl;
print_result();
return;
}
// search_times++;
for(int col=1;col<num+1;col++){
if(check_place(t,col)){
q[t]=col;
queens(t+1);
q[t]=0;
}
}
}
int check_place(int k,int col)
{
for(int j=1;j<k;j++){
if(abs(col-q[j])==abs(k-j)||col==q[j])
return false;
}
return true;
}
void print_result()
{
for(int i=1;i<=num;i++){
cout<<i<<':'<<q[i]<<endl;
}
}
运行结果如下:
#include<stdio.h>
#include<stdlib.h>
#define MAXN 100
#define true 1
#define false 0
void queens(int t);//t表示第t个皇后
void print_queen();
int check_queen(int t,int col);//检查第t个皇后放在位置col是否合理
int n;//解决n皇后问题
int q[MAXN];//记录t皇后的位置
int solve=0;//记录解决方案的个数
int main()
{
scanf("%d",&n);
queens(1);//从第一个皇后开始
return 0;
}
void queens(int t)//t表示第t个皇后
{
int col;
if(t>n){
solve++;
printf("第%d个方案:\n",solve);
print_queen();
return ;
}
for(col=1;col<=n;col++){
if(check_queen(t,col)){
q[t]=col;
queens(t+1);
q[t]=0;
}
}
}
int check_queen(int t,int col)
{
int i;
for(i=1;i<t;i++){
if(q[i]==col||abs(t-i)==abs(col-q[i])){//在同一斜线上或在同一列上
return false;
}
}
return true;
}
void print_queen()
{
int i;
for(i=1;i<=n;i++){
printf("%d:%d\n",i,q[i]);
}
}
运行结果如下:
另外注意:
C语言中,
求整数的绝对值abs()和labs()应该包含stdlib.h
求浮点数的绝对值fabs()应该包含math.h
在C++中,只需要包括cmath即可。