问题描述
八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
解决思路
这个问题可以有两种解决方法,一种是使用递归,比较简单易懂,另一种是使用栈,利用栈的特性避免了递归的使用,从而提高了效率(递归的虽然简单易写,但是其效率往往较低)。
具体实现
首先将节点的坐标定义为结构体:
typedef struct {
int x;
int y;
} Coord;
定义好judge函数(用于判断对应点坐标是否可以放置皇后):
bool judge(SqStack S, int x, int y) {
SqStack m = S;
while (!StackEmpty(m)) {
Coord e;
e = Pop(m);
if ((e.x == x) || (abs(e.x - x) == abs(e.y - y))) {
return false;//如果不行返回false
}
}
return true;//如果可以返回true
}
递归
void Recursive(SqStack &S, int y) {
if (StackEmpty(S)) {
for (int i = 1; i <= N; i) {
Coord e;
e.x = i;
e.y = 1;
Push(S, e);
Recursive(S, 2);
Pop(S);
}
} else if (Full(S)) {
StackTraverse(S);
n ;
return;
} else {
for (int i = 1; i <= N; i) {
if (judge(S, i, y)) {
Coord e;
e.x = i;
e.y = y;
Push(S, e);
Recursive(S, y 1);
Pop(S);
}
}
}
}
这里要注意递归调用Recurive之后要pop出递归之前push进去的,有进就要有出~
非递归
void Search(SqStack s) {
int i = 1;
bool flag;
Coord e;
e.x = 0;
e.y = 1;
while (i <= 8) {
if (flag) {
e.x = 0;
}
if (Full(s)) {
e = Pop(s);
}
flag = false;
for (int j = e.x 1; j <= 8; j ) {
if (judge(s, j, i)) {
Coord e2;
e2.x = j;
e2.y = i;
Push(s, e2);
// cout << "a" << i << "(" << e.y << "," << e.x << ") ";
flag = true;
break;
}
}
if (flag) {
if (i == 8) {
StackTraverse(s);
num ;
} else {
i ;
}
} else {
i--;
e = Pop(s);
if (i == 0) {
break;
}
}
}
}