zoukankan      html  css  js  c++  java
  • n皇后问题(分析)

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

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

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

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

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

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

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

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

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 void function(int a)
     5 {
     6     if (a > 0)
     7     {
     8         printf("%d
    ", a);
     9         function(a - 1);
    10     }
    11 }
    12 
    13 int main(void)
    14 {
    15     int a = 3;
    16     function(3);
    17     system("PAUSE");
    18     return 0;
    19 }

    输出:3 2 1

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 void function(int a)
     5 {
     6     if (a > 0)
     7     {
     8         function(a - 1);
     9                 printf("%d
    ",a);
    10     }
    11 }
    12 
    13 int main(void)
    14 {
    15     int a = 3;
    16     function(3);
    17     system("PAUSE");
    18     return 0;
    19 }

    输出: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种结果。计算机发明后,有多种计算机语言可以解决此问题。

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

  • 相关阅读:
    js 匿名函数的链式调用
    mysql 数据库操作的一般操作命令
    js 截取一定数量的字节
    js 截取10个字节
    BootStrap入门教程 (四)
    安装Dedecms遇到的一系列问题
    BootStrap入门教程 (三)
    dedecms标签调用大全
    artDialog皮肤引入方式
    织梦cms安装完成后登录后台出现空白。主要原因是php版本的问题
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/8506158.html
Copyright © 2011-2022 走看看