算法-深搜

##导语
提到深搜算法,你能想到什么?  φ(≧ω≦*)♪
--深度搜索算法--
--以时间换空间--
---递归实现---
---遍历全部---
-适合算路径个数而不是路径最值-
没错,在我看来深搜算法就是由这样的几个关键字构成的
##主要步骤:
主要分为以下几个简单的步骤: ╰(°▽°)╯
###1.找到起点和终点,并构建一个可以描述所有点的数组,和一个可以表示所有点状态的数组
比如要在一条路上移动,直线型,那么直接一维数组就可以。
比如要在一个5*5构成的方格里移动,那么就是坐标二维数组s5。
###2.构建一个递归函数,函数参数应该最起码包括位置参数和根据题目需求要使用的参数
###3.递归函数里首先列出递归结束的条件,即满足要求或者超出可移动范围或者遇到障碍物等等
###4.接着列出所有~是所有可能移动或者变化的路径
###5.然后这时候就用上了我们之前的状态数组,如果该点未走过且满足条件,将该点状态记为1,然后再进行递归函数,参数为已经变化的点的坐标,这样,在系统进行下一次递归时就会又选择一条路径,继续递归,直到到达起点或超出范围等遇到递归结束条件时,返回上一层,再换一个路,直到全部走完,再返回上层......当然,这些都是系统执行的,我们只用写好递归函数就行。w(゚Д゚)w
###6.在递归函数后,要记得将状态归于0,因为这条路已经走完了,下一条新路这个点还没有走过

好了......我知道我描述的不是很清楚 大家看这些肯定看的一脸懵逼  (@_@?
来个例题吧,一个简单的深搜:


题目 要求:输入一个正整数数(0~200),找到该正整数的一个倍数,并且该倍数的每一位全部由0和1构成,输入0结束输入。
样例输入:
2
6
19
0
样例输出
10
100100100100100100
111111111111111111
(输出只要是所有满足条件倍数中的其中一个答案即可)


分析一下:一位数的只有0.1的数只有1......(别说0啊......0除了0还能是谁的倍数)
二位数的呢?10、11......三位数?100、 101 、110、 110
那么就得出:每一个数的可能情况只有 *10 或者 *10+1

开始写代码:
首先,第1步,起点当然是1开始啊,因为只能是0和1,1肯定在第一位,要不然0*0有什么意义。Σ(っ °Д °;)っ
终点肯定是对输入的数字,取余,为0即就是倍数,满足条件。
第2步:这道题肯定是越计算越大,并且没有路径相通的情况,所以不用标记数组,但是,不能让它无限*下去,即使我们用unsigned long long型,位数也只有20位,所以参数除了现在已经乘到的数,还有位数,也就是步数。

    while(1)
    {
        scanf("%d",&m);
        if(m==0)
            break;
        flag=0;n3=0;
        dfs(1,1);
        printf("%llu\n",n3);
    }

m是输入的数,n3是最终生成的数,标记flag。dfs()函数是这样定义的:

  void dfs(unsigned long long n,int step);

起点为1,位数/步数也为1;
接着第3步:找到终止条件:

  if(n%m==0)
    {
        f=1;
 	    n3=n;
        return ;
    }

列出所有可能性:

	unsigned long long n2;   //引进新变量,防止在进行下一个路径时n的值被改变
	if(f==0 && step<19)      //19位为最大位,再大就超范围,而0~200之间的数20位一定够用
    {
        n2=n*10;
        dfs(n2,step+1);          //满足条件,进入下一层递归
    }
    if(f==0 && step<19)
    {
        n2=n*10+1;
        dfs(n2,step+1);
	}                                //路径全部走完后或者无路可走后返回上一层 
    return ;

是不是很简单?
下面是全部代码:

#include
int m,f;
unsigned long long n3;

void dfs(unsigned long long n,int step);

int main()
{
    while(1)
    {
        scanf("%d",&m);
        if(m==0)
            break;
        f=0;n3=0;
        dfs(1,1);
        printf("%llu\n",n3);
    }
}

void dfs(unsigned long long  n,int step)
{

    unsigned long long n2;

    if(n%m==0)
    {
        f=1;
 	    n3=n;
        return ;
    }
    if(f==0 && step<19)
    {
        n2=n*10;
        dfs(n2,step+1);
    }
    if(f==0 && step<19)
    {
        n2=n*10+1;
        dfs(n2,step+1);
    } 
    return;

}

对于不同的题要求不同,所需要的变量和标记方法也不相同,这个需要大家 因题而异
但是:
深搜的思想是相同的,就是列出所有可能性,找出所有可能性,把所有能走的路径全部走一遍    (゜▽^*))
理解了思想,那么算法题就不在话下啦!
当然如果只需要求出最短路径......那将所以可能路径都跑一遍,再比较,就太浪费时间了
这个时候就需要广搜了,感兴趣的小伙伴可以自己去看看~
简而言之:

深搜是牺牲时间换空间
广搜是牺牲空间换时间
emmmm鱼和熊掌不可兼得? o(╥﹏╥)o
希望到后面能学到......鱼和熊掌都兼得的算法吧......┭┮﹏┭┮

~%?…,# *'☆&℃$︿★?

你可能感兴趣的:(算法题)