研究八皇后问题只是为了学习回溯,可惜还没有开始看回溯就想到了解法,也许这个解法远不如最优解,却磨灭了我学习回溯的动力。先贴上代码,以后可能会补充。
#include
#include
#define CHESS_LOAD 1//棋子落子的时候对势力范围上的操作
#define CHESS_LEAVE -1//棋子离开的时候对势力范围上的操作
using namespace std;
//棋盘上的格子
class mapDot
{
public:
int coverLayerNum = 0;//有多少棋子的范围覆盖在这里
};
typedef vector> mapMat;//定义地图阵列的格式
//用于处理八皇后问题
class problemDealer
{
private:
int mapSize = 0;//棋盘的大小
int chessNum = 0;//棋子的个数
mapMat mainMap;//用于处理数据的棋盘
int answer = 0;
//初始化棋盘
void mapInit();
//将棋盘上的一个格子更改数值
//如果能正常更改,则返回true
bool mapDotChange(int y, int x, int fromValue);
//一个棋子落下的时候调用的函数,fromvalue表示的是落下还是离开
//函数的过程需要在棋子的势力范围上修改势力参数
void chessLoadFunc(int y, int x, int fromValue);
//各种情况枚举的递归操作
//含义上表示剩余几个棋子的时候有多少种放法
int loadChessSitNum(int chessLess);
public:
//fromMapSize表示地图的大小,另一个表示棋子的个数
problemDealer(int fromMapSize,int fromChessNum);
//开始计算
void beginCaclute();
//输出答案的计算结果
void printAns();
};
//初始化棋盘
void problemDealer::mapInit()
{
for (int y = 0; y < mapSize; ++y)
{
//新建一行
mainMap.push_back(vector());
for (int x = 0; x < mapSize; ++x)
{
mainMap[y].push_back(mapDot());
}
}
}
//将棋盘上的一个格子更改数值
//如果能正常更改,则返回true
bool problemDealer::mapDotChange(int y, int x, int fromValue)
{
//判断是否为合法的坐标
if (y < 0)
return false;
if (x < 0)
return false;
if (y >= mapSize)
return false;
if (x >= mapSize)
return false;
//更改数值
mainMap[y][x].coverLayerNum += fromValue;
return true;
}
//一个棋子落下的时候调用的函数,fromvalue表示的是落下还是离开
//函数的过程需要在棋子的势力范围上修改势力参数
void problemDealer::chessLoadFunc(int y, int x, int fromValue)
{
//纵方向
for (int i = 1;; ++i)
{
//判断是否为合法数值,并更改
if (!mapDotChange(y - i, x, fromValue))
break;
}
//左斜方向
for (int i = 1;; ++i)
{
if (!mapDotChange(y - i, x - i, fromValue))
break;
}
//右斜方向
for (int i = 1;; ++i)
{
if (!mapDotChange(y - i, x + i, fromValue))
break;
}
}
//各种情况枚举的递归操作
//含义上表示剩余几个棋子的时候有多少种放法
int problemDealer::loadChessSitNum(int chessLess)
{
//判断递归的返回条件
if (!chessLess)//说明所有的棋子都已经放完
return 1;
int possSitNum = 0;//可能的情况的个数
//根据当前棋子的对应行找这一行上可以落子的地方
for (int x = 0; x < mapSize; ++x)
{
//判断当前位置是否可落子
if (mainMap[chessLess - 1][x].coverLayerNum == 0)
{
//在当前位置落子
chessLoadFunc(chessLess - 1, x, CHESS_LOAD);
//计数可能的情况
possSitNum += loadChessSitNum(chessLess - 1);
//将棋子取下时候的操作
chessLoadFunc(chessLess - 1, x, CHESS_LEAVE);
}
}
return possSitNum;
}
//fromMapSize表示地图的大小,另一个表示棋子的个数
problemDealer::problemDealer(int fromMapSize, int fromChessNum)
{
mapSize = fromMapSize;
chessNum = fromChessNum;
}
//开始计算
void problemDealer::beginCaclute()
{
//初始化棋盘
mapInit();
//判断问题是否可解
if (chessNum <= mapSize)
{
//保存计算结果
answer = loadChessSitNum(chessNum);
}
}
//输出答案的计算结果
void problemDealer::printAns()
{
cout << answer << endl;
}
int main()
{
problemDealer tempDealer(8, 8);
tempDealer.beginCaclute();
tempDealer.printAns();
return 0;
}