八皇后问题

来源:互联网 发布:aes加密java代码 编辑:程序博客网 时间:2024/05/20 02:56

问题描述:八皇后,在8*8的棋盘上放8个棋子,要求各个棋子的行,列,斜线之间不能有两个以上的棋子存在。


问题思考:(个人思考)乍一看题,第一想到的就是回溯,每行最多一个,每行的各个列上可能存在多个解,使用一个循环回溯所有的解。


源代码:

#include <iostream>  
using namespace std;


#define N 8  


bool matrix[N + 1][N + 1] = { 0 };


bool IsLegal(bool matrix[N + 1][N + 1], const int &i, const int &j)
{
for (int m = 1; m <= i - 1; ++m) {
for (int n = 1; n <= N; ++n) {   
if (matrix[m][n] == 1) {
if (n == j || abs(i - m) == abs(j - n))   // 解释一下这一行,因为每次都在下一行放子,所以只需要判断前i-1行的子是否符合要求,这里的n==j表示同列不可,

                                                                                          //abs(i-m)==abs(j-n)表示同斜线不可,无论坐斜线还是右斜线
return false;
}
}
}
return true;
}


void Print(bool matrix[N + 1][N + 1])
{
static int count = 1;
printf("Case %d:\n", count++);
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
matrix[i][j] == 1 ? printf("%d", 1) : printf("%d",0);
}
cout << endl;
}
cout << endl;
}


void Trial(const int i)       //在当前第i行放子
{
if (i > N)   // 当已经输入了N个子,并且符合要求,输出
Print(matrix);
else
for (int j = 1; j <= N; ++j) {
matrix[i][j] = 1;         //在第i行的第j列放子
if (IsLegal(matrix, i, j))    //判断是否符合要求,前i-1行合法
Trial(i + 1);      //继续判断下一行
matrix[i][j] = 0;     //否则,该i,j不可放子,置回0,继续判断i,j+1是否可以放子
}
}

int main(void)
{
Trial(1);    //起始从第一行开始放子
return 0;
}



//////////////////////////////////

代码处理得很简单利落,一开始我在思考处理同斜线上的数时,只想到用斜线上之和不能大于等于2,(现在想到自己蠢爆了,还有自己明明只每行放置了棋子,还加了一个函数判断该行是否符合要求。突然脑壳短路。。),如上就是简单的回溯就可以解决的事~机器就是简单的思考,我们不能添加多余的想法,让代码变得冗余,用最简单的方法告诉机器怎么做,才是高效的。