八皇后问题

问题描述:在一个八乘八的棋盘里,有八个皇后棋子,八个皇后不能同行同列也不能斜着在一条线;请输出所有的八皇后可能。类似如下为一种八皇后排列:
八皇后问题_第1张图片

算法:
1.首先制作一个棋盘(棋盘要有边界,这里的边界为5号ascll码所代表图像)init
2.八皇后要遍历的三个方向(分别为左上,上,右上)。从上向下放,(假如第一行放好后满足左上,上,右上没有皇后,放第二个时候,直到第二行最后一个单元格都没有合适的,那么说明放的位置不对,返回上一行重新放好);chech,find
3.写一个显示函数,show(),和主函数main()

简单遍历,这是一开始的执行,后来就是每次这么循环:

八皇后问题_第2张图片

#include
#include
typedef struct pos{
int ios;
int jos;
}pos_t;

pos_t pos[3]={{-1,-1},{-1,0},{-1,1}};//皇后的三个方向
#define N 8
char board[N+2][N+2];

void init(){//制作一个棋盘
int i,j;
for(i=0;i<N+2;i++){//设置棋盘边界
board[0][i] = 5 ;
board[N+1][i] = 5 ;
board[i][0] = 5 ;
board[i][N+1] = 5 ;
}
for(i=0; i<N; i++){
for(j=1;j<N;j++)
board[i][j]=' ';
}
}
void show(){//显示函数
int i,j;
static int cnt=0;
for(i=0; i<N+2; i++){
for(j=0;j<N+2;j++)
printf("%c",board[i][j]);
printf("\n");
}
printf("cnt=%d\n",++cnt);
}

int chech(int i,int j){//判断皇后的位置
int ret=1;
int p;

for(p=0;ret&&p<3;p++){//p代表三个方向
int ni=i;
int nj=j;//要保存原来的i,j;故定义了ni,nj
while(ret&&board[ni][nj]!= 5 ){//三个方向没有遇到皇后,也没有碰到边界
ni=ni+pos[p].ios;//此处如果p=0,则ni=ni+-1;行数减一
nj=nj+pos[p].jos;//此处如果p=0,则ni=ni+-1;列数减一;同理可得p=1时方
//向为向上移动
if(board[ni][nj]==12)//如果遇到皇后
ret=0;
}
}
return ret;
}

void find (int i){
int j=1;
if( i==9 ){//棋盘最后一行
show();
getchar();//各种情况逐个显示
}else for(j=1;j<=N;j++){
if(chech(i,j)){//调chech函数返回值为ret=1时继续执行
board[i][j] = 12 ;//将皇后放入
find(i+1);//递归,一行一行的检测,第一行放好进行下一行放置
board[i][j]=' ';
}
}
]

int main(int argc,char *argv){
init();
find(1);//皇后放置从第一行开始;调用find函数
return 0;
}
 

运行结果如下:
八皇后问题_第3张图片

你可能感兴趣的:(八皇后问题)