题目本身是回溯法的一种变式。今天趁这个机会回顾了一下回溯法的代码。
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool place(vector<int>position,int pos){
int i=1;
while(i<pos){
if ((position[i]==position[pos])||((abs(position[i]-position[pos])==abs(pos-i))&&abs(pos-i)<3))return false;
//这里是边界条件,也是判断是否继续分支的依据。
i++;
}
return true;
}
int main()
{
int n;
int sumer=0;
cin>>n;
vector<int>position(n+1,0);//初始化。position数组的每一个单元格代表着每一列放在第几行。
int k=1;//由于position是n+1,但是总共只有n列,所以第一列设置为空,
//算法的核心思想:通过k变量表示当前算法正在判断哪一列的皇后。如果k<=0时,说明算法已经将k>0的情况都考虑过了并且运行结束。
while(k>0){
position[k]++;//由于初始化为0,因此进入这一列的时候先默认把皇后放在第一行
while(position[k]<=n && !place(position,k)){
position[k]++;
}//通过while与place函数对这一列的所有行进行判断。其中如果place返回false说明这一行不能放,那么position[k]++来判断下一行。
//如果while满足条件,那么position[k]一定是一个小于等于n的数字,或者不满足条件大于n退出循环
if (position[k]<=n){
//满足place条件退出循环的情况
if (k==n){
sumer++;
//如果k=n,那么说明已经放到第n列并且满足情况了,所以结果++。
}else{
k++;position[k]=0;
//k小于n,说明前n列都已经放置的没有问题,那么就可以放下一列,并且把下一列的原有值设为0.表明重新开始检索。
}
}else{
//不满足place条件退出循环的情况。
//表明这一列没有办法进行,返回上一列。返回上一列之后,通过position[k]++把皇后放到上一列的下一行,重新开始检索。
k--;
}
}
cout<<sumer;
// 请在此输入您的代码
return 0;
}