在8*8的国际象棋棋盘上,安放8个皇后,要求没有一个皇后能够“吃掉”其他一个皇后,即任意两个皇后都不能处于同一行,同一列或同一条对角线上这样的格局称为问题的一个解。(后面有n*n皇后)

步骤:   由于任意两个皇后不能同行,及每一行只能放置一个皇后,因此将第i个皇后放置在第i行中。这样在放置第i个皇后时,只要考虑他与前i-1个皇后处于不同列和不同对角线位置即可。

程序中设计了3个函数:

1.函数Check()用来判断皇后所放位置(row,column)是否可行

2.函数Output()用来输出可行解,及输出棋盘

3.函数EightQueen()采用递归算法实现在row行放置皇后

算法分析:

对于八皇后求解可采用回溯算法,从上之下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解输出结果。

程序流程图:

 

/*author:雷桂艺
time:2021年12月6日16:23
version:1.0
description:每一行只能放置一个皇后,因此将第i个皇后放置在第i行中。这样在放置第i个皇后时,只要考虑他与前i-1个皇后处于不同列和不同对角线位置即可。、
			对于八皇后求解可采用回溯算法,从上之下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解输出结果。
			程序中设计了3个函数:
			1.	函数Check()用来判断皇后所放位置(row,column)是否可行
			2.	函数Output()用来输出可行解,及输出棋盘
			3.	函数EightQueen()采用递归算法实现在row行放置皇后
*/

#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
#define ture 1;
#define false 0;
int num = 0;
char m[8][8] = { '*' };
//m[8][8]表示棋盘,初始为*,表示未放置皇后

//检查在第row行,第column列放置一枚皇后是否可行
BOOL Check(int row, int column)
{
	int i, j;
	if (row == 1)
	{
		return ture;
	}
	for (i = 0; i <= row - 2; i++)//每一列只能有一个皇后
	{
		if (m[i][column - 1] == 'Q')
		{
			return false;
		}
	}
	//左上至右下只能有一个皇后
	i = row - 2;
	j = i - (row - column);
	while (i >=0 && j >= 0)
	{
		if (m[i][j] == 'Q') return false;
		i--;
		j--;
	}
	//右上至左下只能有一枚皇后
	i = row - 2;
	j = row + column - i - 2;
	while (i >= 0 && j <= 7)
	{
		if (m[i][j] == 'Q') return false;
		i--;
		j++;
	}
	return ture;
}

//当为可行解时,输出棋盘
void Output()
{
	int i, j;
	num++;
	printf("可行解 %d:\n", num);
	for (i = 0; i < 8; i++)
	{
		for (j = 0; j < 8; j++)
		{
			printf(" %c", m[i][j]);
		}
		printf("\n");
	}
}

//采用递归函数实现八皇后的回溯算法
//求解当棋盘前row-1行已放置好皇后,在第row行放置皇后
void EightQueen(int row)
{
	int j;
	for (j = 0; j < 8; j++)
	{
		m[row - 1][j] = 'Q';
		if (Check(row, j + 1) == true)
		{
			if (row == 8) Output();
			else EightQueen(row+1);
		}
		m[row - 1][j] = '*';
	}
}

void main()
{
	EightQueen(1);
}

n皇后

算法分析:

对于N皇后求解仍采用回溯算法,从上之下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解输出结果。

但与八皇后问题相比,n皇后问题的难点在与:8皇后由于提前确定了皇后的数量以及棋盘的大小,所以可以在程序中直接开辟好确定的棋盘空间;但n皇后的个数需要从键盘中输入,无法开辟动态的全局变量,只能先开辟一块足够大的存储空间,然后将键盘输入的皇后数量以及棋盘大小通过传参的方式传入函数中,在输出时只输出对应大小的棋盘

程序流程图:

 

#include <stdio.h>
#include <stdlib.h>

typedef int BOOL;
#define ture 1;
#define false 0;
int num = 0;
char p[100][100] = {'*'};//首先要开辟一个足够大的棋盘

//检查在第row行,第column列放置一枚皇后是否可行
BOOL Check(int row, int column,int number)
{
	int i, j;
	if (row == 1)
	{
		return ture;
	}
	for (i = 0; i <= row - 2; i++)//每一列只能有一个皇后
	{
		if (p[i][column - 1] == 'Q')
		{
			return false;
		}
	}
	//左上至右下只能有一个皇后
	i = row - 2;
	j = i - (row - column);
	while (i >= 0 && j >= 0)
	{
		if (p[i][j] == 'Q') return false;
		i--;
		j--;
	}
	//右上至左下只能有一枚皇后
	i = row - 2;
	j = row + column - i - 2;
	while (i >= 0 && j <= number-1)
	{
		if (p[i][j] == 'Q') return false;
		i--;
		j++;
	}
	return ture;
}

//当为可行解时,输出棋盘
void Output(int number)
{
	int i, j;
	num++;
	printf("可行解 %d:\n", num);
	for (i = 0; i <number; i++)
	{
		for (j = 0; j < number; j++)
		{
			printf(" %c", p[i][j]);
		}
		printf("\n");
	}
}

//采用递归函数实现八皇后的回溯算法
//求解当棋盘前row-1行已放置好皇后,在第row行放置皇后
void Queen(int row,int number)
{
	int j;
	for (j = 0; j < number; j++)
	{
		p[row - 1][j] = 'Q';
		if (Check(row, j + 1,number) == true)
		{
			if (row == number) Output(number);
			else Queen(row + 1,number);
		}
		p[row - 1][j] = '*';
	}
}

void main()
{
	int number;
	printf("输入皇后数量(<=100):\n");
	scanf("%d", &number);
	printf("输出最终结果:\n");
	Queen(1,number);
}

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值