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;
}