八皇后问题
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;
}
相关文章推荐
- js: 从setTimeout说事件循环模型
- C++ 初始化类的常量数据成员、静态数据成员、常量静态数据成员
- The Failover Transport(失败故障转移传输)
- SpoolDirectorySource使用及源码分析
- Linux 入门常用命令
- PowerShell实战 第三回 管理AD OU对象
- JavaWeb中的监听器
- 常见设计模式—单例模式/代理模式/责任链模式
- Makefile第四讲:include 引用其它makefile文件
- 除以路径中所有数 时间戳+LCA+路径压缩 2D
- 写一个函数排序整个字符串数组
- webservice生成客户端代码时,出现的问题
- 技术人员为什么要写博客
- Makefile第三讲:终端传值给Makefile、Makefile传值给C++代码
- ssh安全配置
- NOIP2015_day1
- trouble shooting
- PowerShell实战 第二回 管理AD用户对象
- Makefile第二讲:打印出内容和使用变量
- Makefile第一讲:一个简单的Makefile