給定一個4x4的棋盤,要在棋盤上放置4個皇后。他們的位置有這樣的要求,每一列,每一行,每一對角線都能有一個皇后。算法
你可能會對這個對角線有疑惑,其實就是每個小正方形的對角線都不能有皇后。能夠看圖理解一下。
數組
設皇后k擺放在x[k]的位置上,注意數組下標從0開始,0<=k<n且0<=x[k]<n。數據結構
這裏用數組下標以及對應的值,模擬了一個棋盤的行和列。這是比較奇妙的地方,不須要二維數組了。code
算法:setQueen(n)
輸入:皇后的個數n
輸出:n皇后問題的解x[n]。解是一個數組。blog
#include <stdio.h> #include <cstring> #include <math.h> class Queen { private: int Place(int k); int *x; int num; public: Queen(int n); void setQueen(); void PrintQueen(); ~Queen(); }; Queen::Queen(int n) { x = new int[n]; memset(x, -1, n); //-1表示還沒有擺放皇后 num = n; } Queen::~Queen() { delete[] x; } void Queen::setQueen() { int k = 0, count = 0; while (k >= 0) //擺放皇后k,注意0<=k<n { x[k]++; //在下一列擺放皇后k while (x[k] < num && Place(k) == 1) //發生衝突 x[k]++; //皇后k試探下一列,超出num將會跳出 if (x[k] < num && k == num - 1) //獲得一個解 { printf("第%d個解:", ++count); PrintQueen(); } else if (x[k] < num && k < num - 1) //尚有皇后未擺放 k = k + 1; //準備擺放下一個皇后 else x[k--] = -1; //重置x[k],回溯,從新擺放皇后k } } //放置皇后。在一個位置上放置皇后,而後將結果返回。 int Queen::Place(int k) //考察皇后k放置在x[k]列是否發生衝突 { for (int i = 0; i < k; i++) if (x[i] == x[k] || abs(i - k) == abs(x[i] - x[k])) //根據對角線原則 return 1; //衝突返回1 return 0; //不衝突返回0 } //打印皇后的解 void Queen::PrintQueen() { for (int i = 0; i < num; i++) printf("%d\t", x[i] + 1); printf("\n"); } int main(void) { int n; printf("請輸入皇后個數(n>=4):"); scanf("%d", &n); Queen Q(n); Q.setQueen(); return 0; }
這裏面的代碼是來自「數據結構C++王紅梅版」string
也知道了不少新穎的點io
這裏放一波我以前邏輯結構很混亂的代碼(就能夠求解到正確答案,可是輸出的時機很難控制)class
#include <stdio.h> #include <string.h> #include <math.h> #define n 4 //設定n皇后的數目 int *x = new int[n]; void printA(); int place(int k); int main(void) { memset(x, -1, sizeof(int) * n); int k = 0; while (k > -1) { x[k]++; if (k < n && place(k) == 1) //不衝突,開始放置下一行 若是已是最後一行呢? { if (k < n - 1) k++; } else if (k < n || x[k] == n) //要回溯到上一行 { x[k] = -1; k--; } else if (k == n && x[k] < n) { //獲得一組解答 printA(); } } return 0; } //在第k行放置皇后,返回1表明衝突,返回0表明不衝突 int place(int k) { for (; x[k] < n; x[k]++) { bool flag = true; for (int i = 0; i < k; i++) { if (x[k] == x[i] || (abs(k - i) == abs(x[k] - x[i]))) { flag = false; break; } } if (flag) return 1; } return 0; } void printA() { for (int i = 0; i < n; i++) { printf("%d ", x[i] + 1); } printf("\n"); }