一、问题概述
有一个n*n的棋盘,在这个棋盘中放n个皇后,使得这n个皇后,任意两个皇后不在同一行,同一列,同一条对角线。例如,当n等于4时,有两种摆法。
二、思路讲解
随着计算机的普及和发展,以前人们无法解决的问题,计算机可以简单计算出来。而且思路十分清晰,那就是暴力求解,遍历所有情况,然后计算出解的个数。
按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法
三、代码
#include<stdio.h>
#include<math.h>
int rank[20];
bool vis[20];
int n,cnt=0;
void dfs(int pos){
if(pos==n+1){//递归边界条件
cnt++;
return;
}
for(int i=1;i<=n;i++){//枚举每行
if(vis[i]==false){
bool flag=true;
for(int j=1;j<pos;j++){//枚举pos之前的皇后
if(abs(pos-j)==abs(i-rank[j])){
flag=false;
break;
}
}
if(flag){
rank[pos]=i;//pos列在i行
vis[i]=true;
dfs(pos+1);
vis[i]=false;
}
}
}
}
int main(){
scanf("%d",&n);
dfs(1);
printf("%d",cnt);
return 0;
}
四、反思&总结
核心在于,递归思想的应用,在复习离散数学的时候,里面也有这个例子,核心是一种回溯的应用,在一定程度上和树的思想与特点一致。
采用了递归的思路,应用合理的分支预测进行判断。