嘎嘎嘎
#include <stdio.h>
#define N 8
static char board[N+2][N+2];
typedef struct _tag_Pos{
int ios;
int jos;
}Pos;//坐标偏移量结构体定义
static int count = 0;//计数总的放置方式数量
static Pos pos[3] = {{-1,-1},{-1,0},{-1,1}};//三个方向的偏移量数组
void init()//初始化棋盘,要加上边框
{
int i = 0;
for(i = 0;i < N+2;i++){
board[0][i] = '#';
board[N+1][i] = '#';
board[i][0] = '#';
board[i][N+1] = '#';
}
}
void display()//显示棋盘上的情况
{
int i = 0,j = 0;
for(i = 0;i < N+2;i++){
for(j = 0;j< N+2;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
int check(int i,int j)
{
int ret = 1;
int p = 0;
for(p = 0;p <3;p++){//每次以不同的坐标偏移量去循环,为了检查不同的方向
int ni = i;
int nj = j;
while(ret && (board[ni][nj] != '#')){//每次在固定方向循环,直到遇到皇后攻击或者遇到边界
ni = ni + pos[p].ios;
nj = nj + pos[p].jos;
ret = ret && (board[ni][nj] != '*');//将检查结果一方面作为返回值,另一方面作为循环控制条件
}
}
return ret;
}
void find(int i)
{
int j = 0;
if(i > N){
count++;
printf("%d:\n",count);
display();
}else{
for(j = 1;j <= N;j++){//在最外层他会循环8次,每次将第一个皇后放在第一行的不同的列
if(check(i,j)){//
board[i][j] = '*';
find(i+1);//基于第一个皇后的不同的位置,继续找下一个皇后的位置,
//下一个皇后也是放在第二行可以放皇后的所有可能的位置,每次一种情况,依次递归
//然后每一次再找下一个皇后的位置的时候,上述的局部变量全部保存在函数调用的活动记录
//当每弹出一个栈的时候,同时取出局部变量相应的值,有可能i> 8,然后直接显示棋盘情况,
// 有可能j > 8,表示上一个皇后放置错误,只是当时看起来是对的,这里是回溯的关键
board[i][j] = ' '; //回溯算法的体现,每次递归条用结束以后,相当于弹出一个栈空间,此时i的值自动减1,一方面因为有可能之前的皇后实际上不能放在这里
//另一方面将之前在该行放皇后的位置清空,以便下一次基于不同的上一个皇后的位置再重新循环放当前皇后
}
}
}
}
int main()
{
init();
find(1); //从第一行开始寻找合理的位置
return 0;
}