八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。
采用回溯法的技巧,每次把皇后放到一个位置,判断与前面已经放好的皇后是否相互攻击(是否安全),如果安全,此位置计入数组,行数加一, 列数从一开始检查,第八行检查合格后计入标准答案;如果不安全,行数减一,列由刚才计入的加一检查,如果上一行计入的列数已经为八(不能加),行数继续减,直到列数不是八为止,最后第一行的第八列检查不合格后,结束。 入口为第一行第一列。
下面是代码部分:
#include
#include
using namespace std;
#define BOUND 8
bool JudgeSafe(int row, int tempcol); //判断这个点是否安全
void Queue(int row, int currcol);
int *parrcol = (int *)malloc(9 * sizeof(int)); //从1到8储存已经验证的安全位置
/**********全局变量***************/
bool issafe = false;
int tempcol = 1;
int count = 0; //记录答案个数
void main()
{
Queue(1, 1);
free(parrcol); //看编程规范二十六条后添加的两句
parrcol = NULL;
}
/****************判断某一个点是否安全*************************/
/*******与之前的安全点不能同列,或组成的直线斜率不能为正负1***/
/********************col为所在行数****************************/
/*********************tempvol为此时的列数*********************/
bool JudgeSafe(int row, int tempcol)
{
int i = 1;
for(; i < row; i++)
{
if(((row - i) == abs(tempcol - parrcol[i])) || (0 == tempcol - parrcol[i]))
return false;
}
parrcol[row] = tempcol;
return true;
}
/*******迭代调用Queue**********/
/********col为行数*************/
/*********currvol为此时的列数****/
void Queue(int row, int currcol)
{
for(tempcol = currcol; tempcol <= BOUND; tempcol++)
{
issafe = JudgeSafe(row, tempcol);
if(false == issafe)
{
if(BOUND == tempcol) //第8列了,而且不符合,即退回上一行
{
while(BOUND == parrcol[--row]); //上一行也为第8列,继续退
if(row > 0) //第1行到第8列,就结束了
Queue(row, ++parrcol[row]);
}
else continue;
}
else
{
if(BOUND == row) //第8行,符合条件,打印结果,记入答案,
{
count++;
cout<
for(row = 1; row <= BOUND; row++)
cout<<"("<
row--; //跳出循环时row是9
while(BOUND == parrcol[--row]); //退回上一行,如列数已经为8,继续退
Queue(row, ++parrcol[row]);
}
else Queue(++row, 1);
}
}
}
纸上得来终觉浅,绝知此事要躬行。把编程规范二十六条分享给大家:
编程规范二十六条
看看函数头, 注释不能少
变量命名要规范,函数名称要周详
看见数字要谨慎,一不小心鬼上身
PC-Lint不可少, 发现问题速度高
大哥malloc前头走,小弟free来殿后
减法操作要留神,以小减大值翻身
除法运算仔细看,除数为0程序瘫
函数调用要小心,需要判断返回值
看见数组要留神,下标问题常出现
for循环要用好, 边界检查最重要
看见return要注意,要去前面找资源
数据类型可转换,切记用强会失真
内存空间释放后,内存指针要清空
内存拷贝速度快,千万注意莫越界
字节顺序要检查,顺序搞错乱如麻
是非曲直要分辨,不要随便下断言
不要小看字符串,长度算错经常犯
if条件仔细查,千言万语总是假
if失去了else, 流程将会怎么样
构造函数要简单,成员变量要赋值
析构函数多检查,类的资源要释放
多线程技巧高,线程同步要记牢
代码拷贝实在爽,后期维护实在烦
函数肥胖不健康,及时瘦身新时尚
日志打印很重要,问题定位显奇效
编程规范要记牢,代码效率忘不了
最后附录八皇后问题的答案,共92种:
The 1 answer is following:
(1,1)(2,5)(3,8)(4,6)(5,3)(6,7)(7,2)(8,4)
The 2 answer is following:
(1,1)(2,6)(3,8)(4,3)(5,7)(6,4)(7,2)(8,5)
The 3 answer is following:
(1,1)(2,7)(3,4)(4,6)(5,8)(6,2)(7,5)(8,3)
The 4 answer is following:
(1,1)(2,7)(3,5)(4,8)(5,2)(6,4)(7,6)(8,3)
The 5 answer is following:
(1,2)(2,4)(3,6)(4,8)(5,3)(6,1)(7,7)(8,5)
The 6 answer is following:
(1,2)(2,5)(3,7)(4,1)(5,3)(6,8)(7,6)(8,4)
The 7 answer is following:
(1,2)(2,5)(3,7)(4,4)(5,1)(6,8)(7,6)(8,3)
The 8 answer is following:
(1,2)(2,6)(3,1)(4,7)(5,4)(6,8)(7,3)(8,5)
The 9 answer is following:
(1,2)(2,6)(3,8)(4,3)(5,1)(6,4)(7,7)(8,5)
The 10 answer is following:
(1,2)(2,7)(3,3)(4,6)(5,8)(6,5)(7,1)(8,4)
The 11 answer is following:
(1,2)(2,7)(3,5)(4,8)(5,1)(6,4)(7,6)(8,3)
The 12 answer is following:
(1,2)(2,8)(3,6)(4,1)(5,3)(6,5)(7,7)(8,4)
The 13 answer is following:
(1,3)(2,1)(3,7)(4,5)(5,8)(6,2)(7,4)(8,6)
The 14 answer is following:
(1,3)(2,5)(3,2)(4,8)(5,1)(6,7)(7,4)(8,6)
The 15 answer is following:
(1,3)(2,5)(3,2)(4,8)(5,6)(6,4)(7,7)(8,1)
The 16 answer is following:
(1,3)(2,5)(3,7)(4,1)(5,4)(6,2)(7,8)(8,6)
The 17 answer is following:
(1,3)(2,5)(3,8)(4,4)(5,1)(6,7)(7,2)(8,6)
The 18 answer is following:
(1,3)(2,6)(3,2)(4,5)(5,8)(6,1)(7,7)(8,4)
The 19 answer is following:
(1,3)(2,6)(3,2)(4,7)(5,1)(6,4)(7,8)(8,5)
The 20 answer is following:
(1,3)(2,6)(3,2)(4,7)(5,5)(6,1)(7,8)(8,4)
The 21 answer is following:
(1,3)(2,6)(3,4)(4,1)(5,8)(6,5)(7,7)(8,2)
The 22 answer is following:
(1,3)(2,6)(3,4)(4,2)(5,8)(6,5)(7,7)(8,1)
The 23 answer is following:
(1,3)(2,6)(3,8)(4,1)(5,4)(6,7)(7,5)(8,2)
The 24 answer is following:
(1,3)(2,6)(3,8)(4,1)(5,5)(6,7)(7,2)(8,4)
The 25 answer is following:
(1,3)(2,6)(3,8)(4,2)(5,4)(6,1)(7,7)(8,5)
The 26 answer is following:
(1,3)(2,7)(3,2)(4,8)(5,5)(6,1)(7,4)(8,6)
The 27 answer is following:
(1,3)(2,7)(3,2)(4,8)(5,6)(6,4)(7,1)(8,5)
The 28 answer is following:
(1,3)(2,8)(3,4)(4,7)(5,1)(6,6)(7,2)(8,5)
The 29 answer is following:
(1,4)(2,1)(3,5)(4,8)(5,2)(6,7)(7,3)(8,6)
The 30 answer is following:
(1,4)(2,1)(3,5)(4,8)(5,6)(6,3)(7,7)(8,2)
The 31 answer is following:
(1,4)(2,2)(3,5)(4,8)(5,6)(6,1)(7,3)(8,7)
The 32 answer is following:
(1,4)(2,2)(3,7)(4,3)(5,6)(6,8)(7,1)(8,5)
The 33 answer is following:
(1,4)(2,2)(3,7)(4,3)(5,6)(6,8)(7,5)(8,1)
The 34 answer is following:
(1,4)(2,2)(3,7)(4,5)(5,1)(6,8)(7,6)(8,3)
The 35 answer is following:
(1,4)(2,2)(3,8)(4,5)(5,7)(6,1)(7,3)(8,6)
The 36 answer is following:
(1,4)(2,2)(3,8)(4,6)(5,1)(6,3)(7,5)(8,7)
The 37 answer is following:
(1,4)(2,6)(3,1)(4,5)(5,2)(6,8)(7,3)(8,7)
The 38 answer is following:
(1,4)(2,6)(3,8)(4,2)(5,7)(6,1)(7,3)(8,5)
The 39 answer is following:
(1,4)(2,6)(3,8)(4,3)(5,1)(6,7)(7,5)(8,2)
The 40 answer is following:
(1,4)(2,7)(3,1)(4,8)(5,5)(6,2)(7,6)(8,3)
The 41 answer is following:
(1,4)(2,7)(3,3)(4,8)(5,2)(6,5)(7,1)(8,6)
The 42 answer is following:
(1,4)(2,7)(3,5)(4,2)(5,6)(6,1)(7,3)(8,8)
The 43 answer is following:
(1,4)(2,7)(3,5)(4,3)(5,1)(6,6)(7,8)(8,2)
The 44 answer is following:
(1,4)(2,8)(3,1)(4,3)(5,6)(6,2)(7,7)(8,5)
The 45 answer is following:
(1,4)(2,8)(3,1)(4,5)(5,7)(6,2)(7,6)(8,3)
The 46 answer is following:
(1,4)(2,8)(3,5)(4,3)(5,1)(6,7)(7,2)(8,6)
The 47 answer is following:
(1,5)(2,1)(3,4)(4,6)(5,8)(6,2)(7,7)(8,3)
The 48 answer is following:
(1,5)(2,1)(3,8)(4,4)(5,2)(6,7)(7,3)(8,6)
The 49 answer is following:
(1,5)(2,1)(3,8)(4,6)(5,3)(6,7)(7,2)(8,4)
The 50 answer is following:
(1,5)(2,2)(3,4)(4,6)(5,8)(6,3)(7,1)(8,7)
The 51 answer is following:
(1,5)(2,2)(3,4)(4,7)(5,3)(6,8)(7,6)(8,1)
The 52 answer is following:
(1,5)(2,2)(3,6)(4,1)(5,7)(6,4)(7,8)(8,3)
The 53 answer is following:
(1,5)(2,2)(3,8)(4,1)(5,4)(6,7)(7,3)(8,6)
The 54 answer is following:
(1,5)(2,3)(3,1)(4,6)(5,8)(6,2)(7,4)(8,7)
The 55 answer is following:
(1,5)(2,3)(3,1)(4,7)(5,2)(6,8)(7,6)(8,4)
The 56 answer is following:
(1,5)(2,3)(3,8)(4,4)(5,7)(6,1)(7,6)(8,2)
The 57 answer is following:
(1,5)(2,7)(3,1)(4,3)(5,8)(6,6)(7,4)(8,2)
The 58 answer is following:
(1,5)(2,7)(3,1)(4,4)(5,2)(6,8)(7,6)(8,3)
The 59 answer is following:
(1,5)(2,7)(3,2)(4,4)(5,8)(6,1)(7,3)(8,6)
The 60 answer is following:
(1,5)(2,7)(3,2)(4,6)(5,3)(6,1)(7,4)(8,8)
The 61 answer is following:
(1,5)(2,7)(3,2)(4,6)(5,3)(6,1)(7,8)(8,4)
The 62 answer is following:
(1,5)(2,7)(3,4)(4,1)(5,3)(6,8)(7,6)(8,2)
The 63 answer is following:
(1,5)(2,8)(3,4)(4,1)(5,3)(6,6)(7,2)(8,7)
The 64 answer is following:
(1,5)(2,8)(3,4)(4,1)(5,7)(6,2)(7,6)(8,3)
The 65 answer is following:
(1,6)(2,1)(3,5)(4,2)(5,8)(6,3)(7,7)(8,4)
The 66 answer is following:
(1,6)(2,2)(3,7)(4,1)(5,3)(6,5)(7,8)(8,4)
The 67 answer is following:
(1,6)(2,2)(3,7)(4,1)(5,4)(6,8)(7,5)(8,3)
The 68 answer is following:
(1,6)(2,3)(3,1)(4,7)(5,5)(6,8)(7,2)(8,4)
The 69 answer is following:
(1,6)(2,3)(3,1)(4,8)(5,4)(6,2)(7,7)(8,5)
The 70 answer is following:
(1,6)(2,3)(3,1)(4,8)(5,5)(6,2)(7,4)(8,7)
The 71 answer is following:
(1,6)(2,3)(3,5)(4,7)(5,1)(6,4)(7,2)(8,8)
The 72 answer is following:
(1,6)(2,3)(3,5)(4,8)(5,1)(6,4)(7,2)(8,7)
The 73 answer is following:
(1,6)(2,3)(3,7)(4,2)(5,4)(6,8)(7,1)(8,5)
The 74 answer is following:
(1,6)(2,3)(3,7)(4,2)(5,8)(6,5)(7,1)(8,4)
The 75 answer is following:
(1,6)(2,3)(3,7)(4,4)(5,1)(6,8)(7,2)(8,5)
The 76 answer is following:
(1,6)(2,4)(3,1)(4,5)(5,8)(6,2)(7,7)(8,3)
The 77 answer is following:
(1,6)(2,4)(3,2)(4,8)(5,5)(6,7)(7,1)(8,3)
The 78 answer is following:
(1,6)(2,4)(3,7)(4,1)(5,3)(6,5)(7,2)(8,8)
The 79 answer is following:
(1,6)(2,4)(3,7)(4,1)(5,8)(6,2)(7,5)(8,3)
The 80 answer is following:
(1,6)(2,8)(3,2)(4,4)(5,1)(6,7)(7,5)(8,3)
The 81 answer is following:
(1,7)(2,1)(3,3)(4,8)(5,6)(6,4)(7,2)(8,5)
The 82 answer is following:
(1,7)(2,2)(3,4)(4,1)(5,8)(6,5)(7,3)(8,6)
The 83 answer is following:
(1,7)(2,2)(3,6)(4,3)(5,1)(6,4)(7,8)(8,5)
The 84 answer is following:
(1,7)(2,3)(3,1)(4,6)(5,8)(6,5)(7,2)(8,4)
The 85 answer is following:
(1,7)(2,3)(3,8)(4,2)(5,5)(6,1)(7,6)(8,4)
The 86 answer is following:
(1,7)(2,4)(3,2)(4,5)(5,8)(6,1)(7,3)(8,6)
The 87 answer is following:
(1,7)(2,4)(3,2)(4,8)(5,6)(6,1)(7,3)(8,5)
The 88 answer is following:
(1,7)(2,5)(3,3)(4,1)(5,6)(6,8)(7,2)(8,4)
The 89 answer is following:
(1,8)(2,2)(3,4)(4,1)(5,7)(6,5)(7,3)(8,6)
The 90 answer is following:
(1,8)(2,2)(3,5)(4,3)(5,1)(6,7)(7,4)(8,6)
The 91 answer is following:
(1,8)(2,3)(3,1)(4,6)(5,2)(6,5)(7,7)(8,4)
The 92 answer is following:
(1,8)(2,4)(3,1)(4,3)(5,6)(6,2)(7,7)(8,5)