八皇后问题(回溯的算法)

八皇后问题是经典的回溯算法案例,但是对初学者有点难以理解...

基本思路是,从第一个皇后开始放置,同时设置列和左斜和右斜放置标志(如果是从列开始的就设置行的标志)

第i行遍历,如果没有能够放的位置,直接退出函数(也就是不用管),如果没有放到8个,就调用下一个函数,但是仍然在这一级函数之内,所以后续需要回溯以便进行下一个点的搜索。

这样是按照第一行从第一个字开始的输出,如果按列的话,转置矩阵2333333,代码如下:

/*
经典回溯
八皇后问题
按照每一行开始搜索
by Dr.ls
*/
#include<iostream>
using namespace std;
const int size = 9;
int num = 0;
int q[9];//记录每个行的皇后占用的列号
bool line[9];//所在列
bool zuo[17];//所在左斜线i+j
bool you[17];//右斜线
void set(int i)
{
	int j, k, m;
	for (j = 1; j <= 8; j++)
	{
		if ((line[j] == true) && (you[i - j + 9] == true) && (zuo[i + j] == true))
		{
			q[i] = j;//占用ij位置
			line[j] = false;
			you[i - j + 9] = false;
			zuo[i + j] = false;//所在列,斜线均被占用
			if (i < 8)//未到最后一行就调用下一行的函数放置
			{
				set(i + 1);
			}
			else			              // 如果已经放完8个皇后
			{
				num++;		             // 方案数加1
				cout << num << endl;   // 输出方案号
				char zz[17][17];
				for (m = 1; m <= 8; m++)
				{
					for (k = 1; k <= 8; k++)
					{
						if (k == q[m])
						{
							zz[m][k] = '*';
						}
						else if (k != q[m])
						{
							zz[m][k] = '.';
						}
					}
				}//画棋盘
				for (k = 1; k <= 8; k++)
				{
					for (m = 1; m <= 8; m++)
					{
						cout << ' ' << zz[k][m];
					}
					cout << endl;//输出结果
				}
			}
			line[j] = true;
			you[i - j + 9] = true;
			zuo[i + j] = true;//回溯算法,装作无事发生
		}
	}
}
int main()
{
	int i;
	num = 0;
	for (i = 1; i <= 8; i++)
	{
		line[i] = true;
	}
	for (i = 1; i <= 16; i++)
	{
		zuo[i] = true;
		you[i] = true;
	}
	set(1);//从第一行开始放
	return 0;
}


 

猜你喜欢

转载自blog.csdn.net/qq_41565901/article/details/81026524