n皇后问题(分析)

2023-07-29,

这道题需要用到回溯算法,现在在这里先简单的介绍一下这个算法:

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:

1、定义一个解空间,它包含问题的解。

2、利用适于搜索的方法组织解空间。

3、利用深度优先法搜索解空间。

4、利用限界函数避免移动到不可能产生解的子空间。

问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。

首先,看一个简单的程序;

 #include <stdio.h>
#include <stdlib.h> void function(int a)
{
if (a > )
{
printf("%d\n", a);
function(a - );
}
} int main(void)
{
int a = ;
function();
system("PAUSE");
return ;
}

输出:3 2 1

 #include <stdio.h>
#include <stdlib.h> void function(int a)
{
if (a > )
{
function(a - );
printf("%d\n",a);
}
} int main(void)
{
int a = ;
function();
system("PAUSE");
return ;
}

输出:1 2 3

首先第一个不难理解,第二个,首先进行三次递归,分别是function(2),function(1),function(0)=>a=3,a=2,a=1;当到a=1递归执行结束,就会接着往下执行,执行printf,所以此时输出1,然后,返回到上一级递归,function(1),执行结束后,再次执行printf,输出1...

皇后问题:

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

 #include <stdio.h>
#include <stdlib.h> #define max 8//定义最大方格 int a[max],sum=;//定义全局变量 int check_function(int n) { //检查当定一个点时,以行为单位扫描(a[n]为横坐标)遍历其他列的位置是否能满足要求
int i;
for(i=; i<n; i++)/*i<n,而不是i<max,这里用法是:首先定的一个点为起始点,这个点肯定正确,然后对下列扫描,找到,和上一列定那个点一起满足条件的点,接着第三第四列一样,到第八列(max),又找到点时,这时候满足第30行代码的输出条件,输出,找到一组
,接着第26~28行代码,相当于将定点纵坐标加一,进行移位操作,然后到check_function函数中进行与上面类似的操作*/
{
if(a[i]==a[n]||abs(a[i]-a[n])==abs(i-n)) { //a[i]==b[n]表示在同一排的情况,后者为在同一对角线上(记住abs求绝对值函数)
return ;//不满足条件返回1
}
}
return ;//满足条件返回0 } int func(int n) { //定义一个进行对定点改变与输出结果的函数
int i,t;
for(i = ; i < max; i++) {
a[n]=i;//假设的点,当每次满足条件返回1时,会再次进行上面的for循环,对i进行加一操作,相当于对纵坐标操作,下移一位
if(check_function(n)==) { //结合上一个给a[n]赋值,通过判断是否符合条件,让a[n]的值为每一列满足条件的值(纵坐标),n为横坐标
if(n==max-) { //max-1 说的是最后一列,当横坐标数等于最后一列,且满足了检验,就说明这是一组中的最后一个,于是输出满足条件的a[n]
for(t=; t<n; t++)
printf("(%d,%d),",t,a[t]);//这样打印的原因:到这里,每个a[n]实际是满足条件的位置
printf("\n");
sum++;
} else {
func(n+);//若满足了检验,却不满足是最后一项,则说明这只是一组中的一个,且不是最后一个,因为推出结果是按列进行扫描,所以,横坐标向后移一位
}
}
}
} int main(void) {
func();//定横坐标为零
printf("sum=%d\n",sum);//打印出摆放方式数
return ;
}

n皇后问题(分析)的相关教程结束。

《n皇后问题(分析).doc》

下载本文的Word格式文档,以方便收藏与打印。