【无标题】

深度优先搜素(Depth First Search,DFS),DFS的关键在于解决“当下该如何做”。至于“下一步如何做”与“当下如何做”是一样的,比如我们这里写的dfs(step)函数的主要功能是解决当你在第step个盒子的时候你该怎么办。通常的办法就是把每一种可能都去尝试一遍(一般使用for循环来遍历)。当前这一步解决后便进入下一步dfs(step+1)。下一步的解决方法和当前这步的解决方法是完全一样的。下面的代码就是深度优先搜素的基本模型。 

void dfs(int step)
{
    判断边界
    尝试每一种可能 for(i=1;i<=n;i++)
    {
        继续下一步 dfs(step+1);
    }
    返回
}

不撞南墙不回头——深度优先搜素

输入一个数n,输出1~n的全排列
例如有编号为1、2、3的3张扑克牌和编号为1、2、3的3个盒子/现在需要将这3张扑克牌分别放到这3个盒子里,并且每个盒子有且只能放一张扑克牌,那么一共有多少种放法呢
小哼约定了一个顺序:每次到一个盒子面前时,都先放1号,再放2号,最后放三号扑克牌

//这里数组a表示小盒子,变量step表示当前正处在第step个小盒子面前
//a[step]=i;就是将第i号扑克牌放入到第step个盒子里,数组book用来标记哪些牌已经使用了
#include<stdio.h>
int a[10],book[10],n;//c语言的全局变量在没有赋值以前默认为0
int main()
{
    void dfs(int step);
    scanf("%d",&n);
    dfs(1);//首先站在1号小盒子面前
    return 0;
}
void dfs(int step)
{
    int i;
    if(step==n+1)//如果站在第n+1个盒子前,则表示前n个盒子已经放好扑克牌了
    {
        //输出一种排序(1~n盒子中的扑克牌编号)
        for(i=1;i<=n;i++){
            printf("%d ",a[i]);
        }
         printf("\n");
         return ;//返回之前的一步(最近调用dfs函数的地方)
    }
    //此时站在第step个盒子面前,应该放哪张牌呢?
    //按照1、2、3...n的顺序一一尝试
    for(i=1;i<=n;i++){
            //判断扑克牌i是否还在手上
        if(book[i]==0){//book[i]=0表示i号扑克牌在手上
            //开始使用扑克牌i
            a[step]=i;//将i号扑克牌放入第step个小盒子中
            book[i]=1;//i号扑克牌已经不在手中
    //第step个盒子已经放好扑克牌,接下来走到下一个盒子里
            dfs(step+1);//递归调用
            book[i]=0;//一定要将刚才尝试的扑克牌收回,才能进行下一次尝试
        }
    }
    return ;
}

坑爹的奥数——枚举/DFS

【】【】【】+【】【】【】=【】【】【】

将数字1~9分别填入9个【】中,每个数字只能使用一次使得等式成立

枚举

#include<stdio.h>
int main()
{
    int a[10],i,total=0,book[10],sum;
    for(a[1]=1;a[1]<=9;a[1]++)
         for(a[2]=1;a[2]<=9;a[2]++)
          for(a[3]=1;a[3]<=9;a[3]++)
           for(a[4]=1;a[4]<=9;a[4]++)
            for(a[5]=1;a[5]<=9;a[5]++)
             for(a[6]=1;a[6]<=9;a[6]++)
              for(a[7]=1;a[7]<=9;a[7]++)
               for(a[8]=1;a[8]<=9;a[8]++)
                 for(a[9]=1;a[9]<=9;a[9]++){
        for(i=1;i<=9;i++)//初始化book数组
        book[i]=0;
        for(i=1;i<=9;i++)//如果某个数出现过就标记一下
            book[a[i]]=1;
        //统计共出现了多少个不同的数
        sum=0;
        for(i=1;i<=9;i++)
            sum+=book[i];
        //如果正好出现了9个不同的数,并且满足等式条件,则输出
        if(sum==9&&a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9])
        {
            total++;
            printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
        }
    }
    printf("total=%d",total/2);
    return 0;

DFS

//相当于手中有编号为1~9的九张扑克牌,然后将这九张扑克牌放到九个盒子中
#include<stdio.h>
int a[10],book[10],total=0;
int main()
{
    void dfs(int step);
    dfs(1);//首先站在一个盒子前
    printf("total=%d",total/2);
    return 0;
}
void dfs(int step)
{
    int i;
    if(step==10)//如果站在第10个盒子面前,则表示前9个盒子已经放好扑克牌
    {
        //判断是否满足等式
        if(a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9])
        {
            //如果满足要求,加一,并打印这个解
            total++;
            printf("%d%d%d+%d%d%d=%d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
        }
        return ;//返回之前的一步
    }
    //此时站在第step个盒子面前,应该放哪张牌呢?
    //按照1、2、3...n的顺序一一尝试
    for(i=1;i<=9;i++){
        //判读扑克牌i是否还在手上
        if(book[i]==0)
        {
            a[step]=i;
            book[i]=1;
            dfs(step+1);
            book[i]=0;
        }
    }
    return ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值