N 皇后問題:在 N × N 的棋盤上放置彼此不受攻擊的 N 個皇后,任意兩個皇后不同行、不同列、不同斜線。
思路:
1. 因爲皇后不能同行,所以,在每一行放置一個皇后就行
2. 當在一行放置皇后的時候:
1) 順序檢查這一行每一個位置是否和上面所有的皇后,只要有一個同列或者在斜線上就不能放置;若找到一個滿足的,放置在這個位置,開始下一行的皇后放置。
2) 當此行所有位置都不滿足時,回溯到上一行,讓上一個行的皇后繼續選擇下一個合適的位置。
如此,直到所有行上都放上滿足條件的皇后,即爲一個解。
過程如下圖所示:
C++ 代碼
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
class Queen {
private:
int n;
int* x;
int sum;
public:
Queen(int n) {
this->n = n;
sum = 0;
x = new int[n+1];
for(int i=0; i <= n; i++)
x[i]=0;
}
int getSum() {
return sum;
}
void Backtrack(int t) {
if (t > n) {
for(int i=1; i <= n; i++) {
for(int j=1; j <= n; j++)
if(j == x[i])
cout << "Q" << " ";
else
cout << "#" << " ";
cout << endl;
}
cout << endl;
sum++;
} else
for (int i=1; i <= n; i++) {
x[t] = i;
//cout << "i:" << i << " " << "x[t]:" << x[t] << " " << "t:" << t << endl;
if(constraint(t))
Backtrack(t+1);
}
}
bool constraint(int k) {// 約束條件
for (int i=1; i < k; i++)
if((abs(k-i)==abs(x[i]-x[k]))||(x[i]==x[k]))
return false;
return true;
}
~Queen() {
delete[] x;
}
};
int main() {
cout << " ------N皇后問題------" << endl;
cout << "之回溯法求解\n" << endl;
cout << "請輸入皇后的個數:";
int n;
cin >> n;
Queen queen(n);
cout << "\n" << n << "皇后問題的解爲:" << endl;
queen.Backtrack(1);
cout << "\n總共有" << queen.getSum() << "個解" << endl;
system("PAUSE");
return 0;
}