《C和指针》 练习题8.8
代码参考至:https://blog.csdn.net/qq_40421919/article/details/80327639
问题描述
皇后是国际象棋中威力最大的棋子。在下面所示的棋盘上,皇后可以攻击位于箭头所覆盖位置的所有棋子。我们能不能把N个皇后放在棋盘(N×N)上,它们中的任何一个都无法攻击其余的皇后?请编写程序输出皇后的摆放方案,并找出一共有几种方法。
代码
#include<stdio.h>
#define N 8
char board[N+2][N+2]; //一个8*8的棋盘,最外围位置用'#'填充
int count = 0; //用于统计有多少种放置策略
struct Pos
{
int yos; //行偏移量
int xos; //列偏移量
};
//初始化一个结构体数组pos,用于检查'皇后之间'的相对位置是否合理
struct Pos pos[3] = {
{ -1, -1}, //左上偏移
{ -1, 0 }, //向上偏移
{ -1, 1 } //右上偏移
};
//初始化棋盘
void Init(void)
{
int row,col;
int i,j;
for ( row = 0; row < N + 2; row++)
{
for ( col = 0; col < N + 2; col++)
{
board[0][col] = '#';
board[N + 1][col] = '#';
board[row][0] = '#';
board[row][N + 1] = '#';
}
}
for ( i = 1; i <= N; i++)
{
for ( j = 1; j <= N; j++)
{
board[i][j] = ' ';
}
}
}
//显示棋盘(打印数组)
void Show(void)
{
int i,j;
for ( i = 0; i < N + 2; i++)
{
for ( j = 0; j < N + 2; j++)
{
printf("%c", board[i][j]);
}
printf("\n");
}
}
//检查这个位置放置皇后,是否与其他(已放置的)皇后相互排斥
//输入: row行小下标 col列下标
//返回: 1合理 0不合理
int Check(int row, int col)
{
int ret = 1;
int nr;
int nc;
int i;
for ( i = 0; i < 3 && ret; i++)
{
nr = row;
nc = col;
while (ret&&board[nr][nc] != '#')
{
if (board[nr][nc] == '*') //这个位置存在其他'皇后'了
{
ret = 0;
break;
}
nr = nr + pos[i].yos; //偏移下标
nc = nc + pos[i].xos;
}
}
return ret;
}
//采用回溯法,通过递归的手段,找出每一种策略。
//输入: row开始位置的行标
//处理: 将'皇后'们放置结果安排在数组,统计策略总数。
//输出: 打印输出(数组)每一种策略
void Find(int row)
{
int col;
if (row>N) //递归终止条件
{
Show();
count++;
printf("%d\n",count);
}
else
{
for ( col = 1; col <= N; col++) //遍历列 1-8
{
if (Check(row, col))
{
board[row][col] = '*'; //放置
Find(row + 1); //递归调用,遍历下一行
board[row][col] = ' '; //当递归调用返回时(上一次递归被终止),然后执行到这。
//函数会继续for循环判断下一列,检索下一个策略(又是一个递归的过程)
}
}
}
}
int main()
{
Init(); //初始化棋盘
Find(1); //寻找策略
system("pause");
}
展示