皇后问题求解
(1)八皇后问题:
(2)求解思路:
(3)代码实现:
#include <iostream>
#include "Object.h"
#include "LinkList.h"
using namespace std;
using namespace MyLib;
template <int SIZE>
class QueueSolution : public Object
{
protected:
enum { N = SIZE + };
struct Pos : public Object
{
int x;
int y;
Pos(int px = , int py = ) : x(px), y(py) { }
};
int m_chessboard[N][N];
Pos m_direction[];
LinkList<Pos> m_solution;
int m_count;
void init()
{
m_count = ;
// 定义0代表空位置,1代表皇后,2代表棋盘边界
// 初始化棋盘边界
for(int i=; i<N; i+=(N-))
{
for(int j=; j<N; j++)
{
m_chessboard[i][j] = ;
m_chessboard[j][i] = ;
}
}
// 初始化棋盘内部全部为空
for(int i=; i<=SIZE; i++)
{
for(int j=; j<=SIZE; j++)
{
m_chessboard[i][j] = ;
}
}
m_direction[].x = -; // 向左下角扫描
m_direction[].y = -;
m_direction[].x = ; // 向下扫描
m_direction[].y = -;
m_direction[].x = ; // 向右下角扫描
m_direction[].y = -;
}
void print()
{
// 遍历位置坐标链表,输出棋盘上皇后的坐标
for(m_solution.move(); !m_solution.end(); m_solution.next())
{
cout << "(" << m_solution.current().x << ", " << m_solution.current().y << ") ";
}
cout << endl;
// 打印棋盘
for(int i=; i<N; i++)
{
for(int j=; j<N; j++)
{
switch(m_chessboard[i][j])
{
case : cout << " "; break;
case : cout << "#"; break;
case : cout << "*"; break;
}
}
cout << endl;
}
cout << endl;
}
// 检查棋盘上的三个方向是否有其它皇后
bool check(int x, int y, int d)
{
bool flag = true;
do
{
x += m_direction[d].x; // 当前坐标在方向上移动
y += m_direction[d].y;
// 0代表的是空位置,判断在当前方向上是否有其它皇后,若有其它皇后,则循环标志量flag=false;循环退出,函数返回false,意味着在当前方向不能再有皇后;
// 若没有其它皇后,则循环一直在当前方向上查找,直到碰到棋盘边界的代表值2,flag=false,循环退出,函数返回true,说明可以在当前方向上有皇后
flag = flag && (m_chessboard[x][y] == );
}
while(flag);
return (m_chessboard[x][y] == );
}
// 检查第j行有没有可以放置皇后的位置
void run(int j)
{
if(j <= SIZE)
{
for(int i=; i<=SIZE; i++)
{
// 检查在三个方向上都没有其它皇后满足时,才能够放置皇后
if(check(i, j, ) && check(i, j, ) && check(i, j, ))
{
m_chessboard[i][j] = ; // 当前位置可以放置皇后
m_solution.insert(Pos(i, j)); // 将可以放置皇后的坐标保存
run(j + ); // 递归调用查看下一行是否可以放其它皇后
// 当run()函数调用返回时,说明当前位置不能放置皇后,则需要回溯,将之前的标记清空,并且删除链表保存的最后一个位置坐标元素
m_chessboard[i][j] = ;
m_solution.remove(m_solution.length() - );
}
}
}
else
{
// else分支意味着已经查找完了棋盘,找到了一个解决方案
m_count++;
// 打印可行的解决方案
print();
}
}
public:
QueueSolution()
{
// 直接调用init()函数初始化所有数据
init();
}
void run()
{
// 从棋盘的第一行开始查找放置皇后的位置
run();
cout << "Total: " << m_count << " methods" << endl;
}
};
int main()
{
QueueSolution<> qs;
qs.run();
return ;
}
(4)实现结果: