您的位置:首页 > 其它

八皇后问题

2015-11-07 16:59 323 查看

1
问题

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。

2
分析

    采用回溯算法,从上至下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解,输出。

3
实现

#include <stdio.h>

#define TRUE 1
#define FALSE 0

int sum = 0; /*统计解法总数*/
int chsbrd[8][8] = {0};/*八皇后棋盘,初始化为0,未放置皇后*/

/*棋盘前row-1行已经放置了皇后,检查第row行,第colum列放置皇后是否可行*/
int pos_check(int row, int colum)
{
int i,j;

/*首行放置总是可行的*/
if (row == 0)
{
return TRUE;
}

/*判断纵向是否可行*/
for (i = 0; i < row; i++)
{
if (chsbrd[i][colum] == 1)
{
return FALSE;
}
}

/*判断从左上至右下的斜线是否可行*/
i = row - 1;
j = colum - 1;
while (i >= 0 && j >= 0)
{
if (chsbrd[i][j] == 1)
{
return FALSE;
}
i--;
j--;
}
/*判断从右上至左下的斜线是否可行*/
i = row - 1;
j = colum + 1;
while (i >= 0 && j < 8)
{
if (chsbrd[i][j] == 1)
{
return FALSE;
}
i--;
j++;
}

return TRUE;
}

void print_queen()
{
int i,j;

printf("第%d种解法: \n", ++sum);
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
printf("%-2d", chsbrd[i][j]);
}
printf("\n");
}
printf("\n");
}

/*在row行上放置皇后,row的返回为[0,7]*/
void put_queen(int row)
{
int j;

/*在第row行的各列放置皇后*/
for (j = 0; j < 8; j++)
{
chsbrd[row][j] = 1;
if (pos_check(row, j) == TRUE)
{
if (row == 7)
{
print_queen();
}
else
{
put_queen(row+1);
}
}
chsbrd[row][j] = 0;/*回溯*/
}
}

int main()
{
put_queen(0);
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: