您的位置:首页 > 其它

回溯法解决“八皇后”问题

2011-01-23 12:47 337 查看
Technorati 标签: 回溯法,backtrack,八皇后,eight queens puzzle
“回溯法”和“八皇后”问题本身不再多做介绍,相信很多人都知道,尤其是学习过数据结构的人。如果还不清楚可以google或者baidu一下,亦或是找本数据结构的书看一下。

八皇后”问题:可以简单的理解为在一个8*8的棋盘上,放8个旗子(国际象棋中称为皇后queen),要求这8个棋子中任意两个都不在同一行、列、斜线上。

回溯法”用在这里的思路是:
1 逐行放置。
2 对于每一列,从第1列开始(对应矩阵的第0列),逐列测试其是否存在冲突。
2.1 如果冲突就测试下一列,依次进行;
2.2 如果不冲突,放置下一行;

程序代码如下:(如果想更改皇后数量,直接更改queen_number即可,例如:可衍生出在6*6棋盘上放6个皇后)

#include <stdio.h>
#include <stdlib.h>
#define queen_number 8   /* 定义皇后数量 */
int chess_board[queen_number][queen_number]; /* 定义棋盘, 自动初始化为0。 1表示该位置有皇后,0表示没有 */
void print_board(){
int row;
int column;
static int n_solutions;  /* 设置为静态变量,自动初始化为0 */

n_solutions += 1;
printf( "Solution #%d:/n", n_solutions );

for( row = 0; row < queen_number; row += 1 ){
for( column = 0; column < queen_number; column += 1 ){
if( chess_board[ row ][ column ] ){
printf( " Q" );
}else{
printf( " +" );
}
}
putchar( '/n' );
}
putchar( '/n' );
}
/* 检查是否冲突: 1代表冲突,0代表不冲突*/
int conflicts( int row, int column ){
int i;
for(i=1; i<queen_number; i+=1){

/* 检查 “上、左、右” 是否冲突,注意:不需要检查下面,因为下面还没有发放入棋子 */
if(row-i>=0 && chess_board[ row-i][ column ] ){  /* 上 */
return 1;
}
if( column-i>=0 && chess_board[ row ][ column-i]){	/* 左 */
return 1;
}
if( column+i<queen_number&& chess_board[ row ][ column+i]){ /* 右 */
return 1;
}

/* 检查对角线是否冲突,注意:只需要检查“左上方”和“右上方”,因为下面还没有放棋子,“左下方”和“右下方”都不需要检查 */
if(row-i>=0 && column-i>=0 && chess_board[ row-i][ column-i]){	/* 左上方 */
return 1;
}
if(row-i>=0&& column+i<queen_number && chess_board[ row-i][ column+i]){	/* 右上方 */
return 1;
}
}
return  0 ;
}
void place_queen( int row ){
int column;
/* 逐列试验 */
for( column = 0; column < queen_number; column += 1 ){
chess_board[ row ][ column ] = 1;

if(  !conflicts( row, column ) ){  /* 如果不冲突,放置下一行 */
if(row<(queen_number-1)){
place_queen( row+1);	/* 放置下一行 */
}else{	/* 这时已经放置了queen_number行,因为矩阵从第0行开始 */
print_board();
}
}
/* 将皇后移除 */
chess_board[ row ][ column ] = 0;
}
}
int main(){
place_queen( 0 );  /* 从第1行开始放,对应矩阵第0行 */

system("pause");
return EXIT_SUCCESS;
}


参考资料:《C和指针》
本文链接:http://blog.csdn.net/daheiantian/archive/2011/01/23/6225328.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: