您的位置:首页 > 编程语言 > C语言/C++

8皇后-----回溯法C++编程练习

2015-12-23 12:14 411 查看
/*
* 八皇后问题回溯法编程练习
* 在8×8的棋盘上,放置8个皇后,两个皇后之间不能两两攻击
* 也即,直线,垂直45度、135度方向不能出现两个皇后
*
* copyright Michael 2014-12-19
* QQ 1192065414
**/

#include <iostream>
#include <stack>
#include <stdlib.h>
#include <string.h>
using namespace std;

struct Sposition
{
int iRow;
int iColumn;
};

/*
* 保存结果使用的栈
**/
stack<Sposition> ResultStack;

/*
* 推断在水平方向x,垂直方向y,能否够放置新皇后
**/
bool JudgeIsAcceptable(int x ,int y)
{
struct Sposition pos;

stack<Sposition> resultS(ResultStack);
int stackSize = resultS.size();
for ( ; stackSize > 0 ; --stackSize )
{
pos = resultS.top();
if( pos.iRow == x )  //推断同一直线上是否已经有皇后
{
return false;
}

if( (x-pos.iRow) == (y-pos.iColumn) )  //推断45度角是否已经有皇后
{
return false;
}

if( (x-pos.iRow) == (pos.iColumn-y) ) //推断-45度角是否已经有皇后
{
return false;
}

resultS.pop();
}

return true;
}

/*
* 皇后放置算法
* 0 0 0...
* 0 0 0...
* 0 0 0...
* ......
* 遍历第0列,取第0列的第一个、第二个...
* 从第1列開始尝试,然后尝试第2列,当尝试到一列,8行都不能放置皇后,则回溯。返回前一列的下一行继续尝试
**/
void SolveQueue()
{
Sposition pos;
for (int i = 0 ; i < 8 ; ++i )
{
//The first line of the queue
pos.iRow = i;
pos.iColumn = 0;
ResultStack.push(pos);

int x = 0; //标记当前行。0~7行
int y = 1; //标记当前列。0~7列
while( y<8 )  //从第一列開始
{
for ( ; x < 8 ; ++x )  //从第0行開始探索
{
if ( JudgeIsAcceptable(x,y) )
{
pos.iRow = x;
pos.iColumn = y;
ResultStack.push(pos);

//放置完毕。输出结果
if ( 8 == ResultStack.size() )
{
while ( !ResultStack.empty() )
{
pos = ResultStack.top();
cout<<pos.iRow<<"\t"<<pos.iColumn<<endl;
ResultStack.pop();
}
}
x = 0;   //这一列放置完毕,继续下一列放置
break;
}
}

if ( 8 == x )  //这一列。8行都不能放置皇后,回溯到上一列的下一行
{
pos = ResultStack.top();
x  = pos.iRow+1;
if ( 8 <= x )
{
y = y-2;  //假设上一列放置的地方已经是最后一列。则无需继续尝试,应该回溯两列。从前两列继续尝试
ResultStack.pop();
pos = ResultStack.top();
x = pos.iRow+1;
}
else
{
--y;  //回溯到前一列的下一行继续尝试
}
ResultStack.pop();
continue;   //控制列数,不进行 ++y 操作
}

++y;;
}

if ( (8 == y) && (ResultStack.size() != 8) )   //假设8行已经尝试完,可是放置不够8行,出错状态。处理下一种可能性
{
while ( !ResultStack.empty() )
{
ResultStack.pop();
}
}

cout<<endl;
cout<<endl;
}
}

int main()
{
SolveQueue();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: