深搜入门DFS

1、什么是深搜?

        深度优先搜索属于图算法的一种,英文缩写为DFS,即 Depth First Search。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

        举例说明之:下图是一个无向图,如果我们从A点发起深度优先搜索(以下的访问次序并不是唯一的,第二个点既可以是B也可以是C,D),则我们可能得到如下的一个访问过程:A->B->E(没有路了,回溯到A),A->C->F->H->G->D(没有路,最终回溯到A,A也没有未访问的相邻节点,本次搜索结束)。

图

2、深搜框架

void backtrack(int t)
{
        if ( t>n)      // t:递归深度,即当前扩展结点在解空间树中的深度,t>n,搜索至叶子结点
            output(x)  // 记录或输出可行解
        else
            for i=start to end   // strat,end,当前扩展点处未搜索过的子树的起始编号和终止编号
            {
                x[t]=h(i)       // h(i):当前扩展点处x[t]的第 i 个可选值
                if (当前扩展结点的约束条件)
                    backtrack(t+1)
            }
}

3、从枚举到深搜

        一个三位数abc,如果满足abc = a^3+ b^3+ c^3,那么就把这个数叫做水仙花数。如果一个N位数所有数码的N次方的和加起来等于这个数字本身,我们把这样的数叫做广义水仙花数,现在,我们的任务是,输入一个m (m<7),让你求出所有满足N = m的广义水仙花数。

样例输入1:3          样例输出2:153 370 371 407

样例输入2:5          样例输出:54748 92727 93084

分析:

        如果是水仙花问题,可以用枚举,直接求出。代码如下:

#include <stdio.h>
int main()
{
	int i,a,b,c;
	for(i=100;i<=999;i++)
	{
		a=i/100;
		b=i/10%10;
		c=i%10;
		if(a*a*a+b*b*b+c*c*c==i)
			printf("%d ",i);
	}
	printf("\n");
    return 0;
}

或:

#include <stdio.h>
int main()
{
	int a,b,c;
	for(a=1;a<=9;a++)
		for(b=0;b<=9;b++)
			for(c=0;c<=9;c++)
				if(a*a*a+b*b*b+c*c*c==a*100+b*10+c)
					printf("%d%d%d ",a,b,c);
	printf("\n");
    return 0;
}

        现在求广义的水仙花,现在的难点是不知道是几位数?也不知道是几次方?循环层数不确定,那么该如何实现m重循环?答案只有一个:就是递归,让系统自动调用函数,自动实现循环。

        套用上面深搜(回溯)模板,代码自然而成。

#include <stdio.h>
#include <math.h>
int n;
void flower(int t,int curNum,int curSum)
{
	int i,start;
	if(t>n)
	{
		if(curNum==curSum)
			printf("%d ",curNum);
	}
	else
	{
		start=(t==1);  // 第一位不为0,第一位1~9枚举,其他位0~9枚举 
		for(i=start;i<=9;i++)
			flower(t+1,curNum*10+i,curSum+(int)pow(i,n));
			// 缩小问题规模
	}
}
int main()
{
	while(scanf("%d",&n) && n)
	{
		flower(1,0,0);
		printf("\n");
	}
	return 0;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值