八皇后问题
- 题目描述
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 皇后以行,列,对角线移动,如果一个皇后通过移动可到达另一皇后的位置,即可以攻击到。
-
解题思路
每个皇后必须在不同的行(n个皇后,n行),所以我们只要考虑记录下每行皇后所在的列位置
-
相关解题法
矩阵维护法:
定义:每一行至多有一个元素是特殊值,其余为元素为0或一个常数,通过r[j]=i或c[i]=j,来记录特殊元素的坐标(由稀疏矩阵引申?)
优势:省去坐标的传递和管理,用r[],c[]来记录行,列坐标
递归法:函数自己调用自己
以下三种还不会(手动狗头投降)
迭代法:手动对栈法:
回溯法
-
解题代码(上一个比较舒服的)
#include <iostream>
using namespace std;
# include <cmath>
//递归算法解决八皇后问题。总共有92种解法。
int c[9], n = 8, cnt = 0;//全局变量 c[]数组用来储存对应皇后的列坐标
void print() {
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (j == c[i]) cout << "1 ";
else cout << "0 ";
}
cout << endl;
}
cout << endl;
}
void search(int r) { //r:已经摆好的皇后数(r当前列坐标)
if (r == n) { //总的皇后数=摆好的皇后数(不满足r<n,行坐标越界结束)
print();huang
++cnt; //解法加一
return;
}nzuobiao
for (int i = 0; i < n; ++i) {
c[r] = i; //记录第r个皇后的列坐标
int ok = 1;
for (int j = 0; j < r; ++j)
//检查列坐标是否满足与前面皇后的列坐标的关系
if (c[r] == c[j] || r - j == abs(c[r] - c[j]) ) {
//行距和列距相同满足对角线
ok = 0;
break;
}
if (ok) search(r + 1);//如果当前列坐标可用进入下一个皇后的列坐标寻找
// 遍历每一个分支
}
}
int main() {
search(0);
cout << cnt << endl;
return 0;
}