八皇后问题

原创 2013年12月09日 22:16:46

 

分析:
对这个问题,首先我们看问题的答案,最后的结果是输出棋盘,最重要的是我们发现,最后有Queen_Max个皇后被放置好了,且每行只有一个皇后,我们很容易想到用递归解决这个问题,因为当别人帮你放好七个皇后时,你很乖就可以放好第八个,最多尝试Queen_Max次。要用递归,首先我们要想好出口,如果我们用一个数queen_number来记录已经放好的皇后的个数,不难发现,出口是当queen_number等于Queen_Max时,直接打印棋盘。要放置皇后,首先应判断,是否所选的位置能放皇后,这就要求我们写一个判断queen[x][y]是否能放皇后的函数,很容易发现这个函数中我们只要判断点(x, y)正上方,左上方,右上方三个方向是否由皇后存在,有则不能放,否则能放置。对于放置皇后的函数本人认为最难的是解决当一行都不能放置的时候,要返回上一行,而且要把上一行的皇后初始化,使要放置的位置指向原来放置皇后位置的右边,然后继续放置的问题。这一块也很难理解。
对于这一问题,因为我们使用的是递归,所以函数在调用自身时会自己保存,原来放置皇后的位置也就是下面代码的queen[x-1][i],我们要做的只是当一次调用完成时将原来放置的皇后初始化,也就是queen[x-1][i]=0,这一块我建议最好能自己调试一下,了解整个函数的过程,调试时可以把Queen_Max改成4,这样能简单一点。具体的代码如下:
 


#include<stdio.h>

#define Queen_Max 8
int queen_number=0; //表示已经放皇后的个数
int k=0;

int queen[Queen_Max][Queen_Max]; // 用二维数组表示棋盘
int judge_queen(int x, int y);
void place_queen(int x);

int main()
{
         int i, j;
         //初始化,将整个二维数组的数赋值为1
          for(i=0; i<Queen_Max; i++)
                 for(j=0; j<Queen_Max; j++)
                      queen[i][j]=0;
          place_queen(0);
         return 0;
}
//判断queen[x][y]这个点能否方皇后,能返回1,否则返回0;
int judge_queen(int x, int y)
{
        if(queen[x][y]==1)     return 0;
        int i, j;
       //检查改点上部是不是有皇后
         for(i=0; i<x; i++)
                   if(queen[i][y]==1)     return 0;
        //检查左上是否有皇后
          i=x, j=y;
          while(i>=0 && j>=0) {
                     if(queen[i--][j--]==1) return 0;
           }
//检查右上是否由皇后
           i=x, j=y;
           while(i>=0 && j<Queen_Max) {
                   if(queen[i--][j++]==1) return 0;
           }
            return 1;
}
放置皇后,完成后并打印数组,用到了递归,x表示放置的行数
void place_queen(int x)
{
         int i, j;
//出口,如果放的皇后数等于Max则打印出数组,
          if(queen_number==Queen_Max) {
                    printf("µÚ%d×é½â\n", ++k);
                     for(i=0; i<Queen_Max; i++) {
                               for(j=0; j<Queen_Max; j++) {
                                        printf("%2d", queen[i][j]);
                                 } 
                                 puts(" ");
                      }
                      puts(" ");
         }
//如果能queen[x][i]能放置,则将其赋值为1,用递归执行下一行,
          for(i=0; i<Queen_Max; i++) {
                   if(judge_queen(x, i)) {
                              queen[x][i]=1;
                              queen_number++;
                               place_queen(++x);
                             queen[x-1][i]=0; //往上返回时,要恢复数组到没有执行操作之前, 一次恢复只恢复一次, 同时记录放置皇后的数减一
                              queen_number--;
                                --x;
                   }
           }
}

 

 

 


 

版权声明:本文为博主原创文章,未经博主允许不得转载。

八皇后及其拓展问题

  • 2017年12月02日 14:41
  • 181KB
  • 下载

利用c++解决八皇后问题

  • 2017年11月27日 23:51
  • 784B
  • 下载

回溯法和栈的思想用于“八皇后问题”的求解

八皇后问题是一个经典的问题,其核心是:在n*n的棋盘上,有n个皇后,这些皇后必须位于不同行不同列上,并且不能处于同一对角线上,否则会因相互攻击而死亡。那么如何安排皇后们的位置呢? 我们可以利用回溯法,...

八皇后问题源码 python

  • 2017年12月04日 18:52
  • 6KB
  • 下载

八皇后问题的C++实现

  • 2017年09月23日 08:39
  • 446KB
  • 下载

回溯法解决八皇后问题(java实现)

算法课上需要用回溯法解决八皇后问题,八皇后问题就是国际象棋棋盘(8*8)上摆放8个棋子,同一横行、竖行、斜线上不能摆放棋子,问有多少种摆法。 回溯法是五大常用算法之一。...

八皇后问题

  • 2015年12月14日 16:22
  • 119KB
  • 下载

八皇后问题

  • 2015年07月07日 18:13
  • 36KB
  • 下载

java利用递归解决八皇后问题

问题简介: 要求在一个8*8的棋盘上放置8个皇后,使任意两个皇后都不同行不同列且不在同一条斜对角线上。采用递归和回溯的思想解决这一问题是较为直观的。一开始,棋盘上的任意格子都可落子,因此可任意选择第...

八皇后问题的C语言程序

  • 2014年09月12日 17:14
  • 516KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:八皇后问题
举报原因:
原因补充:

(最多只允许输入30个字)