递归回溯 N皇后问题 四种写法详解(C语言/C++——一维数组/二维数组)

N皇后问题,做之前感觉挺难,但做着做着发现其实还挺简单的。用递归写的代码简直不要太简洁!

令N=8,效果如图:
在这里插入图片描述

在这里我列出了四种解法,具体讲解见注释:
C语言解法
C++解法
C语言解法升级版
C++解法升级版

其中普通版利用的是二维数组,升级版用的是一维数组。
用二维数组来做直观,好理解,但效率比用一维数组低。

感觉 面向对象的C++ 的确和 面向过程的C 在思想上有较大区别,以前真的是拿C++当C用,,,

话不多说,开始解题。

二维数组解法

C语言

(用到了我之前从来没用过的全局变量)
(不过老师上课好像讲过不建议定义全局变量。。)

#include<stdio.h>
#define maxsize 20
#define occupied 1
#define not_occupied 0

/** 全局变量定义棋盘,
*	这样调用函数时就不用把这个二维数组传来传去了。**/
bool queen_square[maxsize][maxsize]={
   not_occupied};
int size;
int answer_num=1;

/**三个函数分别用来:
*   检查当前位置可不可以放
*   打印棋盘
*   递归求解    **/
bool unguarded(int row, int col);
void print();
void solve(int row);

unguarded函数:判断当前位置是否可以放
(因为我写的这个递归是从最下面的一行开始放皇后,所以要检查的是当前行的“下面的”棋盘)

bool unguarded(int row, int col)
{
   
    bool ok=true;
    int i=0;

    for(i=0 ; i<size && ok ;i++)//检查该列
    {
   
        if(queen_square[i][col]==occupied)
            ok=false;
    }
    for(i=1 ; row+i<size&&col+i<size&&ok ; i++)//检查指向左下的对角线
    {
   
        if(queen_square[row+i][col+i]==occupied)
            ok=false;
    }
    for(i=1 ; row+i<size&&col-i>=0&&ok ; i++)//检查指向右下的对角线
    {
   
        if(queen_square[row+i][col-i]==occupied)
            ok=false;
    }
    return ok;
}

print函数:打印棋盘,无需赘述。

void print()
{
   
    printf("THE %d ANSWER:\n\n",answer_num++);
    for(int i=0;i<size;i++)
    {
   
        for(int j=0;j<size;j++)
        {
   
            if(queen_square[i][j]==occupied)
                printf(" O ");
            else printf(" + ");
        }
        printf("\n\n");
    }
    printf("\n\n");
}

solve函数:递归函数,在第row行放皇后。

void solve(int row)
{
   
    if(row<0)//row=-1,说明第零行已经放上了皇后,所以此时要把棋盘打印出来
        print();
    else
    {
   
        for
  • 9
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值