八皇后問題:遞迴解決/C語言(基礎方法)
阿新 • • 發佈:2019-02-11
/************************* *八皇后問題:遞迴解決/C語言 *按照8層8叉樹來想象,共有8^8種可能,對應每個葉子節點; *由根到葉子,自左至右遍歷每種情況; *剪枝掉不可行的方案; *及時輸出可行方案,繼續遍歷; *其間並未對每種可行方案累計儲存; *所有呼叫的遞迴完成返回後,程式結束。 ******************** *Author: Joy/王曉雪 *Date: 04/11/2015 19:51 Sat. **************************/ #include <stdio.h> #include <string.h> #define N 8 int column[N+1]; //標記每列是否有QUEEN,有為1,無為0. int right_up[N*2]; //從右上到左下方向的對角線/,(i,j)在第(i+j-1)列. int left_up[N*2]; //從左上到右下方向的對角線\,(i,j)在第(N-j+i)列. int queen[N+1]; //記錄每行queen所在的列號. int cnt; //表示第cnt個解決方案. void init(); //初始化陣列及變數 void backtract( int i ); //回朔遞迴求解,i定位第i行的queen. void showAnswer(); //列印輸出當前儲存的解決方案 int main() { init(); backtract( 1 ); return 0; } void init() { cnt=0; //標記N個queen在棋盤上的位置 memset( column, 0, sizeof(column) ); //初始化為0,表示空閒; memset( right_up, 0, sizeof(right_up) ); //初始化為0,表示空閒; memset( left_up, 0, sizeof(left_up) ); //初始化為0,表示空閒; memset( queen, 0, sizeof(queen) ); //初始化為0,表示queen未標記; } void backtract( int i ) { int j; if( i<=N ) //對第i個queen. { for( j=1; j<=N; j++ ) //遍歷每一列 { //滿足:該列為空 && 該(i,j)的雙向對角線均為空. if( 0==column[j] && 0==right_up[i+j-1] && 0==left_up[N-j+i] ) { //將第i個queen放在第j列 queen[i] = j; column[j] = 1; right_up[i+j-1] = 1; left_up[N-j+i] = 1; //遞迴:向下一層尋找 backtract(i+1); //遞迴返回:已找到一種解決方案 或 第i+1行無法擺放成功; //放棄標記在(i, j)的queen,尋找該行的下一個可能列. column[j] = 0; right_up[i+j-1] = 0; left_up[N-j+i] = 0; } } } else //N個queen均已放置好,列印輸出此種解決方案 { showAnswer(); } } void showAnswer() { int i, j; printf("\nAnswerCase%d:\n", ++cnt); for( i=1; i<=N; i++ ) //列印第i行的queen位置. { for( j=1; j<=N; j++ ) { if( j == queen[i] ) { printf(" Q"); } else { printf(" ."); } } printf("\n"); } }
參考資料:http://www.oschina.net/code/snippet_234517_12132