八皇后問題,即在乙個棋盤上,每行都可以放置乙個皇后,但每個皇后都不能影響其他皇后的安全,即所有皇后的位置不能在同一直線上
解決問題方法及思想 : 遞迴
在使用遞迴之前首先要準備好兩個函式實現:
1.判斷此時此刻位置是否安全 (只需要判斷元素上方,左上方,右上方是否安全,且只要有乙個位置不安全,則結束判斷!)
2.如果已經完成乙個能將皇后安全放置的棋盤,則輸出
完整**:
#include #define n 8
#define boolean int
#define true 1
#define false 0
boolean issafe(int (*chessboard)[n], int row, int col);
void drawchessboard(int (*chessboard)[n]);
void nqueen(int (*chessboard)[n], int row);
void nqueen(int (*chessboard)[n], int row) else
chessboard[row][col] = 0; //無論本行是否安全,都應該去掉本位置的皇后,因為下一列需要放置乙個皇后
} }}void drawchessboard(int (*chessboard)[n])
printf("\n");
} printf("\n");
}boolean issafe(int (*chessboard)[n], int row, int col)
} //判斷元素左上方是否有皇后
for(i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
} //判斷元素右上方是否有皇后
for(i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++)
} return true;
}int main() ; //建立乙個棋盤,並將所有元素賦初值為0,如果放置皇后,則賦值為1
nqueen(chessboard, 0); //將棋盤位址傳進,從下標為0的第一行開始進行位置判斷
}
一些問題補充說明:
指標與二維陣列:
int a[3][4]; a是二維陣列的名字,是乙個指標常量,它指向的是它所屬元素的首元素,它的每乙個元素是乙個行陣列,因此它的指標移動單位是「行」,故a+i指向的是是第i個行陣列,即指向a[i]. 該過程也可以描述為: int *p; p = a[0];
對上述a陣列,行陣列指標定義如下:
int(*p)[4]; 表示陣列*p有4個int型元素,分別為(*p)[0], (*p)[1], (*p)[2], (*p)[3], 即p指向的是有4個int型元素的一維陣列,即p為行指標
此時,關於nqueen的傳參問題就變得簡單:
在主函式呼叫中 : nqueen(chessboard, 0); chessboard是乙個二維陣列名稱,即乙個指標常量,指向第乙個行陣列
而在函式實現中 : void nqueen(int (*chessboard)[n], int row); 定義乙個行指標chessboard, 指向n個int型元素(注意形參和實參中的chessboard是不一樣的)
這樣實參傳的是行位址,而形參指向行元素,沒有問題
遞迴實現N皇后問題
因為每行只能放置乙個皇后,故可用一維陣列a儲存 第i行皇后的列數,即 a i j 表示第i行的皇后位於第j列。為方便起見,下標全部從1開始。它可以實時表示擺放的狀態。遞迴函式 queen i 可理解為 我們已經無衝突的擺放好了前 i 1 行的皇后並在陣列a中儲存,現在開始擺放第i行的皇后。對於第i行...
八皇后問題(遞迴實現)
八皇后問題,是乙個古老而著名的問題,是回溯 的典型案例。該問題是國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8x8格的西洋棋 上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。這裡用遞迴演算法實現,因為遞迴在某個層面上就實現了回溯,再演算法中,...
八皇后問題(遞迴實現)
八皇后問題是回溯法的典型例題,就同一問題有許多不同種解法,這裡只通過遞迴解決八皇后問題 所謂八皇后問題是由高斯先生提出的乙個關於西洋棋的數學問題,其要求在8x8的棋盤上放置8個皇后,每個皇后之間不能互相攻擊到對方 皇后的攻擊方式是公尺字型 高斯先生窮其一生發現了76鐘解法,在沒有計算機的年代已經非常...