思路分析:用递归,进行深度遍历,保证每次新皇后地加入不受前面加入的皇后影响。
代码分析:
1.解题用的是一维数组,每次递归完成后,该数组的数正是八个皇后从第一行到第八行所处的列数,之所以用一维数组,是方便判断皇后们是否在相同的一列、相同的对角线。
2.nums[i]=j表示这个皇后处在第i行第j列上
3.三个函数:递归dfs、判断本次皇后所处位置是否得当、输出函数
4.这个递归函数没有出口,因为里面有的是for循环
5.判断是否在同一对角线的原理:坐标上的斜率(x1-x2)/(y1-y2)==1
#include<iostream>
#include<math.h>
using namespace std;
int total=0;
bool fun(int nums[],int rows){
for(int i=1;i<rows;i++){//保证先前的皇后和本次rows行的皇后不在线上
if(nums[rows]==nums[i]||(abs(rows-i)==abs(nums[rows]-nums[i])))
return false;
}
return true;
}
void show(int nums[],int total){
cout<<"这是第"<<total<<"组结果:"<<endl;
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
if(nums[i]==j) cout<<"X"<<" ";
else cout<<"O"<<" ";
}
cout<<endl;
}
}
void dfs(int nums[],int rows){
for(int i=1;i<=8;i++){//从1到8,共8列
nums[rows]=i;//第rows行第i列
if(fun(nums,rows)){//表示rows行i列可以放皇后
if(rows==8){//计算到了8行了没有,到了的话可以停止
total++;
show(nums,total);
}
else dfs(nums,rows+1);
}
else nums[rows]=0;//不合适即为0,没有皇后,不写也可以,写了只是方便理解
// if(rows==8) 这不能写,会漏判
// return ;
}
}
int main(){
int nums[10]={0};
for(int i=1;i<=8;i++)
cout<<nums[i]<<" ";
cout<<endl;
int rows=1;//第row行
dfs(nums,rows);
cout<<"一共"<<total<<"种结果"<<endl;
return 0;
}
思路来源:b站up主“大红豆小薏米” https://www.bilibili.com/video/av58557186?from=search&seid=1000981574024305137
up讲解用的python