题目说明:
西洋棋中的皇后可以直线前进,吃掉遇到的所有棋子,如果棋盘上有八个皇后,则这八个皇后如何相安无事的放置在棋盘上,1970年
与1971年,E.W.Dijkstra与N.Wirth曾经用这个问题来讲解程式设计之技巧。
题目解析:
关于棋盘的问题,都可以用递回求解,然而如何减少递回的次数?在八个皇后的问题中,不必要所有的格子都检查过,例如若某列检查
过,该该列的其它格子就不用再检查了,这个方法称为分支修剪。
程序代码:
#includeusing namespace std;const int N_SIZE = 8;/// 使用数组记录状态int UpperOblique[2*N_SIZE + 1] = { 0};int LowerOblique[2*N_SIZE + 1] = { 0};int Column[N_SIZE + 1] = { 0};int Queen[N_SIZE + 1] = { 0};int Number = 0;void ShowResult(){ cout << "\nNO " << ++Number << ":" < N_SIZE) ShowResult(); else { for (int j=1; j<=N_SIZE; ++j) { if (Column[j]==0 && UpperOblique[i-j+N_SIZE]==0 && LowerOblique[i+j]==0) { Queen[i] = j; Column[j] = UpperOblique[i-j+N_SIZE]=LowerOblique[i+j]=1; BlackTrack(i+1); Column[j] = UpperOblique[i-j+N_SIZE]=LowerOblique[i+j]=0; } } }}int main(){ BlackTrack(1); return 0;}
#include#include using namespace std;const int N_SIZE = 8;int Record[N_SIZE+1] = { 0}; /// 记录每列选择的位置int ResultNum = 0;bool Check(int x){ for (int i = 1; i N_SIZE) { ShowResult(); } else { for (int j=1; j <=N_SIZE; ++j) { Record[x] = j; if (Check(x)) { BackTrack(x+1); } } }}int main(){ BackTrack(1); return 0;}
还有诸如 遗传算法、退火算法、位运算和基于Q一矩阵的快速搜索算法。但是这些算法中,遗传算法和基于Q一矩阵的快速搜索算法一般只能得到部分解;退火算法得到的解往往是近似解,存在一定的误差:位运算依赖硬件,32位机器只能计算32皇后,如果要计算任意皇后,需要增加变量,会带来额外的系统开销和编程难度。