一般是八皇后,首先是算法思想如下:
void generate(int n){
int col;
for(col=0;col<=7;col++){
if(不衝突){
放置,並且宣佈佔領
if(n<7){
generate(n+1);
}else{
printf();//打印
}
回溯,取消佔領.
}
}
}
主函數如下:首先從0開始,也就是第一行開始逐級向下
int main(){
generate(0);
cout<<"擺放方式有:"<<counts<<"種!"<<endl;
return 0;
}
遞歸函數如下:
void generate(int n){
int col;
for(col=0;col<8;col++){//棋盤一共八行八列,此處主要是每一層用於判斷每一列是否符合條件
if(flag[col]&&d1[n-col+7]&&d2[n+col]){//括號內是算法的精髓,理解了此處,N皇后問題就不難,主要是根據八皇后棋盤的性質,
//如兩個座標,如果行數-列數對應的值相同,那麼就必然在同一對角線,此時跳出if從而判斷下一位置
Queens[n]=col;//符合上述條件之後,就把皇后放置在col列,並且把相對於的列,上對角線,下對角線的標記改爲false,方便之後的判斷
flag[col]=false;
d1[n-col+7]=false;
d2[n+col]=false;
if(n<7){
generate(n+1);
}else{
print();
}
flag[col]=true;//回溯考慮上一層的情況,並且把這一層改過來的false改爲true
d1[n-col+7]=true;
d2[n+col]=true;
}
}
}
輸出函數如下:
void print(){
int col,i,j;
counts++;
cout<<"No."<<counts<<endl;
int table[8][8]={};//定義一個8*8的棋盤數組,起始每個元素都是0
for(col=0;col<8;col++){
table[col][Queens[col]]=1;//Queens[col]保存的是皇后所在的列數
}
for(i=0;i<8;i++){
for(j=0;j<8;j++){
cout<<table[i][j]<<" ";
}
cout<<endl;
}
}
頭部聲明以及全局變量如下:
#include <iostream>
#include <algorithm>
using namespace std;
int Queens[8]={};//表示第n個皇后佔位置的列號
int counts=0;//counts記錄能擺放的棋盤方式個數
bool flag[8]={1,1,1,1,1,1,1,1};//標誌數組,表示第col列是否可佔,1表示可佔
bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示上對角線是否可佔 爲什麼是15呢?
//因爲在d1[n-col+7]中爲了避免出現負數,所以要+7,而原來可能是7的現在變成了14
bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};//表示下對角線是否可佔