递归三部曲之深入理解八皇后问题

什么是八皇后问题?

所谓的八皇后问题就是指在一个8*8的棋盘中按要求摆放八颗棋子,使得这个棋盘中的每一行,每一列,和每一条对角线上都只能有一颗棋子。要求你输出所有满足要求的棋子的摆放方式。

问题分析:

模拟人手动去摆放这些棋子的放法,我们应该是先摆放第一个,然后再找到下一个满足要求的为止进行摆放,以此类推,直至八颗棋子摆放完成。
在实际的程序中其实也是这样的,我们发现8颗棋子要不在同一行,所以每行都必须有一颗棋子。于是我们可以用a[i]来表示一颗棋子的准确位置,i表示行,a[i]的值表示列。
当第一次所有的位置都确定好之后我们就输出这些解,然后呢?其实接下来要做的和全排列就有一些相似之处了,就是不断的变换上一颗棋子的位置,然后得出新的解了,这个其实就是回溯了啊。

代码与分析:

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
int a[100], n, count;
bool check (int a[ ],int n)
{
    for(int i=1;i<=n-1;i++)
    {
        if((abs(a[i]-a[n])==n-i)||(a[i]==a[n]))
            return false;
    }
    return true;
}
void dfs(int k)
{
    if (k>n)
    {
        for(int i=1;i<=8;i++)
        {
            cout<<a[i];
        }
        cout<<endl;
        count++;
    }
    else
    {
        for (int i = 1;i <=n; i++)
        {
            a[k] = i;
            if (check(a,k) == 1)
            {
                dfs(k+1);

            }
        }
    }
}
int main()
{
    n=8,count=0;
    dfs(1);
    cout<<count<<endl;
}
第一个check()函数就是检查位置是否合法的函数,这里不再解释。
接下来的是dfs(int k),这个函数就是我们进行深搜回溯的函数了,其中的参数k表示的是当前正在摆放哪一行的棋子,当K>8的时候,自然前面八行都摆放完毕了,故输出结果。接下来的代码就是核心了:
 for (int i = 1;i <=n; i++)
        {
            a[k] = i;
            if (check(a,k) == 1)
            {
                dfs(k+1);

            }
        }
首先我们进行分析,我们第一次调用的时候是dfs(1),所以是a[1]=1,然后紧接着是dfs(2),同理a[2]=1,2,,,,,n,但是前两个已经不符合条件,故应该是a[2]=3,.....一次类推,直至到dfs(8)之后最后一层的递归结束,然后会调回dfs(7)dfs(8)
dfs(6)dfs(7)dfs(8).......这个就是前两篇中我们提到的栈结构啦。。。。

总结:

通过这三篇,我们从初识递归,到深入理解递归。在此过程中想必大家也跟我一样获益良多吧。所以,赶紧同我一样与小伙伴们分享吧,欢迎转载。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值