資料結構程式設計回顧(三)八皇后問題(遞迴)
阿新 • • 發佈:2018-12-31
設計要求:八皇后問題是在8×8 的國際象棋棋盤上安放8
個皇后,要求沒有一個皇后能夠“吃掉”任何其他一個皇后,
即沒有兩個或多個皇后佔據棋盤上的同一行、同一列或者同
一條對角線。
說明:在實際問題中,有相當一類問題需要找出它的解集合,
或者要找出某些約束條件下的最優解。求解時通常使用一種
稱為回溯的方法來解決,所謂回溯就是走回頭路,該方法是
在一定的約束條件下試探地搜尋前進,若前進中受阻,則回
頭另擇通路繼續搜尋。
由於作者比較懶,當年就用了遞迴實現而已,沒有用棧的非遞迴實現。
由定義可知,每行必定有且僅有一個皇后,使用一維陣列儲存即可,每個元素儲存這一行元素的位置。
根據已知條件(同行、同列或同一一條線)不能放置兩個皇后(後來知道皇后是可以橫著走斜著走豎著走的,如果滿足這些條件會被吃掉),判斷第n行第i列是否能放置皇后:
int puts(int n,int i){
int j;
for(j=0;j<n-1;j++){
if(queens[j]==i||((n-j)==(queens[n]-queens[j]))||((n-j)==(queens[j]-queens[n])))
return 0;
}
return 1;}
遞迴體:
如果n==總行數,即0~n-1已經放置完成,則解法+1,並輸出改解法。
否則,對這行的每個位置進行判斷是否能放置,如果能,則進行下一行的放置,否則,退回上一層,繼續測試上一層的下一個位置。
int queen(int n){
if(n==num)
{ c++;
print();
return 0;
}
int i;
for(i=0;i<num;i++){
queens[n]=i;
if(puts(n,i)==1){
queen(n+1);
}
}
}
、
完整程式碼:
#include <iostream> #include <string.h> //八皇后問題 int queens[100]; int num; int c; using namespace std; void print(){ int i,j; cout<<endl<<"---------------"<<endl; cout<<"第"<<c<<"種解法"<<endl; for(i=0;i<num;i++){ for(j=0;j<num;j++){ if(queens[i]==j) cout<<'T'; else cout<<'O'; cout<<' '; } cout<<endl; } } int puts(int n,int i){ int j; for(j=0;j<n-1;j++){ if(queens[j]==i||((n-j)==(queens[n]-queens[j]))||((n-j)==(queens[j]-queens[n]))) return 0; } return 1;} int queen(int n){ if(n==num) { c++; print(); return 0; } int i; for(i=0;i<num;i++){ queens[n]=i; if(puts(n,i)==1){ queen(n+1); } } } int main() { cout<<"N queens problem\n"<<"pls input n:"; cin>>num; queen(0); cout<<"共有"<<c<<"種解法."; return 0; }