一个典型的回溯法!作为练习。
有几个关键地方需要注意,就是判断皇后的位置是否合法。
pos[i] 表示第i个皇后应该排在的位置。
因此对于第k个皇后而言,需要满足 pos[i]!=pos[k] 同时 abs(i-k)!=abs(pos[i]-pos[k])
#include <iostream>
using namespace std;
bool canPlace(int pos[], int k){
for(int i = 0 ; i < k; ++i)
if(i!=k && pos[i]!=-1 &&
(pos[i]==pos[k] || // 不在同一行上
abs(pos[i]-pos[k]) == abs(i-k))) // 不在同一斜线上
return false;
return true;
}
void printPos(int pos[], int n){
for(int i = 0 ; i< n ; ++i)
cout<<pos[i]<<' ';
cout<<endl;
}
void nQueen(int n ){
int *pos = new int[n];
int k = 0;
memset(pos,-1,sizeof(int)*n);
while(k >= 0){
++pos[k];
while(pos[k]<n && !canPlace(pos,k))
++pos[k];
if(pos[k] < n){
if(k== n-1)
printPos(pos,n);
else
k++;
}else
pos[k--] = -1;
}
delete[] pos;
}
int main(){
nQueen(8);
cout<<"system"<<endl;
system("PAUSE");
return 0;
}
一个简单方法就是回溯法来生成一个排列,代码如下,可以比较一下两个代码之间的区别于联系。
void combination(int n){
int *num = new int[n];
memset(num,0,sizeof(int)*n);
num[0] = 1;
while(true){
for(int i = 0 ; i < n; ++i)
cout<<num[i]<<' ';
cout<<endl;
int k = n-1;
while(k>=0){
if(num[k]<9){
++num[k];
break;
}else
num[k--] = 0;
}
if(k<0)
break;
}
delete[] num;
}