八皇后问题是在8*8的棋盘上放置8枚皇后,使得棋盘中每个纵向、横向、左上至右下斜向、右上至左下斜向均只有一枚皇后。八皇后的一个可行解如图所示:
思路
对于八皇后的求解可采用回溯算法,从上至下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解,输出。
此处可用借鉴陈海涛网易博客中的思路,不用二维数组,而采用一维数组进行回溯,参见http://www.cnblogs.com/jiayouwyhit/p/3226757.html。因为1维数组的下标即可表示行或者列,再在一维数组里面赋值,即可代表列或者行。此条件即可至少满足八皇后问题的一个条件:两个皇后不同行或者不同列。省去后文的一个步骤判断。
本人参考网上别人的回溯思路,写的代码如下:(注意,本代码已经在VC6.0下通过实验测试)
//8皇后问题
//基于递归的回溯算法
const int length=8;
int counter=0;
bool Check(int matrix[], int row)//检验是否合理
{
int i=0;
for (i=0;i<=row-1;i++)
{
if (matrix[i]==matrix[row] || row-i==matrix[row]-matrix[i] ||i-row==matrix[row]-matrix[i])
return false;
}
return true;
}
void EightQueen(int matrix[], int row)
{
int i=0,j=0;
for (i=0;i<length;i++)
{
matrix[row]=i;
if (Check(matrix,row) && row<=length-1)//满足要求
{
if (row==length-1)
{
++counter;
printf("Solution %d:\n",counter);
for (j=0;j<length;j++)
printf("%4d",matrix[j]);
printf("\n");
}
else
EightQueen(matrix,row+1);
}
}
}
int main(int argc, char* argv[])
{
int matrix[length]={0};
EightQueen(matrix,0);
printf("We have solved the problem!\n");
return 0;
}
复杂度分析:本文算法的时间复杂度为O[n^(n+1)]。比http://www.cnblogs.com/jiayouwyhit/p/3226757.html时间复杂度更高.
实际上,经过实际的实验测试,本文的算法实际上在时间上要比前面提到的算法性能要好很多。经过仔细分析,其原因在于:本文算法中对递归有一个限制条件
Check(matrix,row),即:当当前点不满足我们的约束条件时,直接就不再进行递归,因此函数void EightQueen(int matrix[], int row) 的时间复杂度会远远小于O[n^n](假如不考虑check函数自身的时间复杂度的话)。但该算法具体的时间复杂度是多少,由于有判断语句的存在,本人觉得此处无法写出具体的复杂度表达式(再一次说明本人数学功底还有待提高啊\(^o^)/~)。