20150410 递归实现八皇后问题

20150410 递归实现八皇后问题

2015-04-10 Lover雪儿

十九世纪著名的数学家高斯1850年提出:

在8x8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意的连个皇后都不能处于同一行、同一列或者统一斜线,问有多少种摆法。

以下是其中一种解法,如图所示:

当年高斯先生没日没夜的计算,得出结论是76种。

其实正确的结论是92中,此处我们就来编程计算一下正确的答案。

  1 //八皇后问题
  2 #include <stdio.h>
  3
  4 static int count = 0;    //算法的总数
  5
  6 //判断第row行第col列位置是否有危险,是否在其他皇后的攻击范围
  7 //没有危险,则返回真
  8 int NotDanger(int row, int col, int (*chess)[8]){
  9     int i, k;
 10     int flag_1=0, flag_2=0, flag_3=0, flag_4=0, flag_5=0;
 11     //判断列的方向有没有危险 标志位flag_1
 12     for( i=0; i<8; i++)
 13     {
 14         if( *(*(chess + i)+ col) != 0)    //判断是否有棋子
 15         {
 16             flag_1 = 1;
 17             break;
 18         }
 19     }
 20     //判断左上方有没有危险 标志位flag_2
 21     for(i = row, k = col; i>=0 && k>=0; i--, k--)
 22     {
 23         if(*(*(chess + i)+k) != 0)
 24         {
 25             flag_2 = 1;
 26             break;
 27         }
 28     }
 29     //判断右下方有没有危险 标志位flag_3
 30     for(i = row, k = col; i<8 && k<8; i++, k++)
 31     {
 32         if(*(*(chess + i)+k) != 0)
 33         {
 34             flag_3 = 1;
 35             break;
 36         }
 37     }
 38     //判断右上方有没有危险 标志位flag_4
 39     for(i = row, k = col; i>=0 && k<8; i--, k++)
 40     {
 41         if(*(*(chess + i)+k) != 0)
 42         {
 43             flag_4 = 1;
 44             break;
 45         }
 46     }
 47     //判断左下方有没有危险 标志位flag_5
 48     for(i = row, k = col; i<8 && k>=0; i++, k--)
 49     {
 50         if(*(*(chess + i)+k) != 0)
 51         {
 52             flag_5 = 1;
 53             break;
 54         }
 55     }
 56     if( flag_1 || flag_2 || flag_3 || flag_4 || flag_5){
 57         return 0;
 58     }else{
 59         return 1;
 60     }
 61 }
 62
 63 //八皇后算法 row:起始行 col:列数 *chess[8]:指向棋盘每一行的指针
 64 void EightQueen(int row, int col, int (*chess)[8])
 65 {
 66     int chess_tmp[8][8], i, j;
 67     for(i = 0; i<8; i++){
 68         for(j = 0; j<8; j++){
 69             chess_tmp[i][j] = chess[i][j];
 70         }
 71     }
 72     //当指针走到了第八行时,说明已经计算好,打印出棋盘
 73     if( 8 == row){
 74         printf("第 %d 种方法:\n",count+1);
 75         for(i = 0; i<8; i++){
 76             for(j = 0; j<8; j++){
 77                 printf("%d ",*(*(chess_tmp+i)+j));
 78             }
 79             printf("\n");
 80         }
 81         printf("\n\n");
 82         count++;
 83     }else{
 84         //判断这个位置是否有危险,是否在其他皇后的攻击范围
 85         //如果没有危险,继续往下判断,知道row = 8
 86         for( j=0; j<col; j++){
 87             if(NotDanger(row, j, chess_tmp)){        //判断是否危险
 88                 for(i = 0; i<8; i++){                //将整行所有的列赋值为0
 89                     *(*(chess_tmp + row)+i) = 0;
 90                 }
 91                 *(*(chess_tmp + row)+j) = 1;
 92                 EightQueen(row+1, col, chess_tmp);  //递归调用
 93             }
 94         }
 95     }
 96 }
 97
 98 int main(void)
 99 {
100     int chess[8][8], i, j;
101
102     //初始化八皇后的棋盘,1:放置皇后 0:没有皇后
103     for(i = 0; i<8 ; i++){
104         for(j = 0; j<8 ; j++){
105             chess[i][j] = 0;
106         }
107     }
108
109     freopen("EightQueen.txt", "w", stdout); //重定向输出到out.txt文件中
110
111     EightQueen(0 , 8, chess);
112     printf("总共有 %d 种解决方法\n\n",count);
113
114     return 0;
115 }

运行成功后在当前文件夹生成一个文件EightQueen.txt,内容如下所示:

时间: 2024-12-15 01:34:03

20150410 递归实现八皇后问题的相关文章

递归解决问题——八皇后

这是一个比较经典的算法问题了,也是用到了递归思路,采用了递归回溯法 public class Queue8 { int max = 8; int[] array = new int[max]; static int count = 0; static int judgeCount = 0; public static void main(String[] args) { Queue8 queue8 = new Queue8(); queue8.check(0); System.out.print

八皇后解法(回溯法)

package com.company; /** * Created by Administrator on 2016/9/15. */public class EigthQueue { private static int N = 8; private int count = 0; // 总方案数 private int[] flag = {-1, -1, -1, -1, -1, -1, -1, -1}; //回溯法递归实现八皇后问题 //输出棋盘 private void printChes

java实现八皇后问题(递归和循环两种方式)

循环方式: package EightQueens; public class EightQueensNotRecursive { private static final boolean AVAILABLE = true; private int squares = 8, norm = squares - 1; private int positionInRow[] = new int[squares]; private int p=-1; private boolean[] rows = n

C#中八皇后问题的递归解法——N皇后

百度测试部2015年10月份的面试题之——八皇后. 八皇后问题的介绍在此.以下是用递归思想实现八皇后-N皇后. 代码如下: using System;using System.Collections.Generic; namespace QueensSolution { class Program { static int count = 0; static void Main(string[] args) { int n = Int32.Parse(Console.ReadLine()); L

八皇后问题,递归法实现

八皇后问题,是19世纪著名的数学家高斯在1850年提出的:在8×8格的国际象棋盘上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列.同一斜线上,试问有多少种摆法?高斯先生给出的答案是“76”种,实际是76种吗? 八皇后问题是回溯算法的典型应用,但是本文提供递归的求法. 递归的核心思想可以总结成:把一个复杂的问题无限缩小,每个小问题的解法都是一样的,最终归结于求解每个小问题的原型.递归编程的思路可以假设所有的问题都已解决,来到结束条件,这是非常简单的,然后再调用自身求解整个问

递归的应用——八皇后问题

回朔算法的基本思想 ·从问题的某一种状态出发,搜索可以到达的状态 ·当某个状态到达后,可向前回退,并继续搜索其他可达状态 ·当所有状态都到达后,回朔算法结束 程序设计中可以利用函数的活动对象保存回朔算法的状态数据,因此可以利用递归完成回朔算法. 八皇后算法 1 初始化 I = 1 2 初始化 J = 1 3 从第i行开始,恢复j的当前值,判断第j个位置 A`位置j可放入皇后:标记位置(i,j),i++,转步骤2 B`位置j不可以放入皇后:j++,转至步骤A C`当j>8时,i--,转至步骤3 4

八皇后问题递归代码

听了下别人的讲解后,最后仔细理解了下所谓的八皇后问题. 怎么说呢,感觉有点像搜索的做法. #include<stdio.h> int count=0; //row行,j列: int notDanger(int row,int j,int (*chess)[8]){ int i,k,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0; //注意这里row与j不能直接使用: //判断列的方向有无危险: for(i=0;i<8;i++){ if(*(*(chess+

递归之回朔算法应用----八皇后问题

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

八皇后问题——递归+回溯法

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 高斯认为有76种方案.1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果. 求解过程: 采用遍历的办法,就是采用将每种情况都验证的办法最终找出问题的解,但是蛮力遍历的话,需要遍历的数据量太大,计算时间花费太大,所以在遍历