递归问题之八皇后问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26822029/article/details/81254785

八皇后问题:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

解决思路:仔细分析这个问题,发现为了满足要求每一次放置棋子的时候肯定要放置在不同行,那么可以将问题简化为:从第一行开始,第一次将棋子放在第一行的某个位置,第二次放在第二行的某个位置...以此类推,那么第八次将棋子放在第八行的某个位置(如果存在这个位置的话)。因此可以利用类似递归的方法解决这个问题,我们定义一个eightQueen函数,参数为当前放置棋子的行数,通过递归调用便可以轻松求出所有的解。

判断能否放置在某一位置:在判断的时候需要对某一个点position(x, y)进行列和对角线的判断,因此需要5个判断。(这里不需要判断行是因为每一次放置都是在新的一行放置,不存在重复的问题!)。

最终的完整程序为:

#include <iostream>
using namespace std;

int EQMap[8][8] = {0};
int counter = 1;

bool isThisPlaceOK(int x, int y)
{
	// check if position(x, y) is safe in col.
	for(int i = 0; i < 8; i++)
	{
		if(EQMap[i][y] == 1)
		{
			return false;
		}
	}

	// west-north
	for(int i = x, j = y; i >= 0 && j >= 0; i--, j--)
	{
		if(EQMap[i][j] == 1)
		{
			return false;
		}
	}

	// west-south
	for(int i = x, j = y; i < 8 && j >= 0; i++, j--)
	{
		if(EQMap[i][j] == 1)
		{
			return false;
		}
	}

	// east-south
	for(int i = x, j = y; i < 8 && j < 8; i++, j++)
	{
		if(EQMap[i][j] == 1)
		{
			return false;
		}
	}

	// east-north
	for(int i = x, j = y; i >= 0 && j < 8; i--, j++)
	{
		if(EQMap[i][j] == 1)
		{
			return false;
		}
	}
	return true;
}

void printMap()
{
	for(int i = 0; i < 8; i++)
	{
		for(int j = 0; j < 8; j++)
		{
			cout << EQMap[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}

void eightQueen(int curRow)
{
	if(curRow == 8)
	{
		cout << "map " << counter++ <<endl;
		printMap();		
		return;
	}

	for(int j = 0; j < 8; j++)
	{
		if(isThisPlaceOK(curRow, j))
		{
			EQMap[curRow][j] = 1;
			eightQueen(curRow + 1);
		}
		EQMap[curRow][j] = 0;
	}
	return;
}

int main()
{
	eightQueen(0);
	return 0;
}

 

 

猜你喜欢

转载自blog.csdn.net/qq_26822029/article/details/81254785