/* file name: queen.c Description: 利用遞迴法求出 8 個皇后問題之解 */ #include #include #define TRUE 1 #define FALSE 0 #define MAXQUEEN 5 #define ABS(x) ((x>0) ?(x): -(x)) /* 求x之絕對值 */ /* 存放 5 個皇后之列位置,陣列註標為皇后的行列值 */ int queen[MAXQUEEN]; int total_solution; /* 計算共有幾組解 */ /* 函數原型宣告 */ void place(int); int attack(int, int); void output_solution(void); int main() { place(0); /* 從第 0 個皇后開始擺放至棋盤 */ return 0; } void place(int q) { int i; i = 0; while ( i < MAXQUEEN ) { if (!attack(i, q)) { /*皇后未受攻擊*/ queen[q] = i; /* 儲存皇后所在的列位置 */ /* 判斷是否找到一組解 */ if (q == MAXQUEEN-1) output_solution(); /* 列出此組解 */ else place(q+1); /* 否則繼續擺下一個皇后 */ } i++; } } /* 測試在(row, col)上的皇后是否遭受攻擊 若遭受攻擊則傳回值為 1,否則傳回 0 */ int attack(int row, int col) { int i, atk = FALSE; int offset_row, offset_col; i = 0; while (!atk && i < col) { offset_col = ABS(i - col); offset_row = ABS(queen[i] - row); /* 判斷兩皇后是否在同一行,皇后是否在對角線上 */ /* 若皇后同一行或對角線上,則會產生攻擊, atk == TRUE */ atk = (queen[i] == row) || (offset_row == offset_col); i++; } return atk; } /*列出 5 個皇后之解*/ void output_solution() { int x,y; total_solution += 1; printf("Solution #%d\n\t", total_solution); for ( x = 0; x < MAXQUEEN; x++ ) { for ( y = 0; y< MAXQUEEN; y++ ) if ( x == queen[y] ) printf("Q"); else printf("-"); printf("\n\t"); } printf("\n"); }