八皇后问题
八皇后问题
是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
以4皇后为例,如图所示,在图(a)中,第1行第1列上放置一个皇后,图(b)中确定第2行的可能放法,在尝试第1列、第2列由于相互攻击而放弃之后,确定在第3列放置可以继续,在图(c)中继续对第3行进行考察,发现将所有4列都尝试过了,也没有办法将皇后安排一个合适的位置,对第4行做任何的尝试都没有意义,这时产生回溯,结果是在图(d)中将第2行的皇后安排到第4列,然后第3行的暂时可以放在第2列,在图(e)中试着确定第4行的皇后,却发现无解再次回溯,只能够如图8.22(f)所示将第1行的皇后放到第2列,再经图(g)、(f)之后找到4皇后问题的一个解,那就是图(g)的(2, 4, 1, 3)。
搞清楚用回溯法求解的过程后,将关注什么样的解才是可行的?需要描述出任何两个皇后可以“互相攻击”这样的条件:
(1)有两个皇后处在同一行
(2)有两个皇后处在同一列
(3)有两个皇后处在同一斜线
所以我们只需要判断不满足上述三个条件即可!
假设此时位置处于X,只要遍历(x-1,y-1)、(x-1,y)、(x-1,y+1)三个方向,只要能在等于 ” * ” 前找到等于 “ # ”,就说明此方向没有皇后。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#define N 8
char board[N + 2][N + 2];
typedef struct Pos
{
int xos;
int yos;
}pos_t;
pos_t pos[3] = { //定义1个结构体,表示移动的位数(x-1,y-1)\(x-1,y)\(x-1,y+1)
{ -1, -1 },
{ -1, 0 },
{ -1, 1 }
};
void Initboard()//初始化棋盘
{
int i, j = 0;
for (i = 1; i <= N; i++)
{
for (j = 1; j <= N; j++)
{
board[i][j] = ' ';
}
}
for (i = 0; i <= N+1; i++)
{
board[0][i] = '#';
board[i][N + 1] = '#';
board[N + 1][i] = '#';
board[i][0] = '#';
}
}
void display()//显示棋盘
{
int i, j = 0;
for (i = 0; i < N + 2; i++)
{
printf("------------------------------\n");
for (j = 0; j < N + 2; j++)
{
printf("%2c|", board[i][j]);
}
printf("\n");
}
printf("\n");
}
int check(int i, int j)//检查当前行是否可以放。返回0说明不能放;1能放
{
int k = 0;
int ret = 1;
for (k = 0; k < 3; k++)
{
int nx = i;
int ny = j;
while (ret && (board[nx][ny] != '#'))
{
if (board[nx][ny] == '*')
ret = 0;
nx += pos[k].xos;
ny += pos[k].yos;
}
}
return ret;
}
void Find(int line)
{
static int count = 0;
if (line > N)
{
count++;
printf("共有%d种情况\n", count);
display();
}
else
{
int j = 0;
for (j = 1; j <= N; j++)
{
if (check(line,j))
{
board[line][j] = '*';
Find(line + 1);
board[line][j] = ' ';// 下一行不能放,说明当前行的当前位置不合适
}
}
}
}
int main()
{
Initboard();
Find(1);
system("pause");
return 0;
}
回溯法
回溯法是一种通用的搜索算法,几乎可以用于求解任何可计算的问题。算法的执行过程就像是在迷宫中搜索一条通往出口的路线,总是沿着某一方向向前试探,若能走通,则继续向前进;如果走不通,则要做上标记,换一个方向再继续试探,直到得出问题的解,或者所有的可能都试探过为止。
上一篇: 杨辉三角
推荐阅读
-
.htaccess文件问题
-
php-PHP调用.NET写的web service时异常,这一般是什么问题。异常错误信息如下
-
分享微信扫码支付开发遇到问题及解决方案-附Ecshop微信支付插件_PHP
-
求 数据库的update语句有关问题
-
for循环 - 新手PHP代码问题,求解关于simple_html_dom
-
Symfony2.6.3 生成repository的问题
-
Jquery 表格合并的问题分享_jquery
-
Struts中的URL传递的问题(forward标签的redirect属性)
-
问一个mysql,group by 日期分组查询的有关问题
-
JQery jstree 大数据量问题解决方法_jquery