步骤: 由于任意两个皇后不能同行,及每一行只能放置一个皇后,因此将第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);
}