算法课程笔记——DFS基础&回溯

隐式保存

不能用bool?

#include<stdio.h>

int a[10],book[10],n;

//这里还有需要注意的地方C语言全局变量默认为0

void  dfs(int step){ //此时在第step盒子面前,需要往里面放第i张扑克牌

int i;

if(step==n+1){    //这里说明前面的n个盒子已经放好了,这是dfs结束的标志

for(i=1;i<=n;i++)

printf("%d",a[i]);

printf("\n");

return ;

/*

注意这个 return 它的作用不是返回主函数,而是返回上一级的dfs函数

例:如果此时是  dfs(5),遇到这个 return 就会回到上一级的 dfs函数

也就是dfs(4),但此时dfs(4)的大部分语句已经执行了,只需要接着执行 book[i]=0

然后继续进入for循环进入下一次的 dfs函数,直到结束。                 

*/

}

 for(int i=1;i<=n;i++){

if(book[i]==0){  //说明i号扑克牌还在手里,需要放入step号盒子

a[step]=i;//将i号扑克牌放到第step个盒子中

book[i]=1;//此时i号扑克牌已经被使用                

dfs(step+1);

/*注意这里是自己调用自己,表示此时走到了第step+1个盒子面前*/                

book[i]=0;

/*book[i]=0表示dfs调用结束了,换句话说就是扑克牌已经全部放完了

  需要按照顺序将扑克牌收回,重新放,也就是前面所说的

 */

}

}

return;//这里表示这一级别的dfs函数已经结束了,返回上一级 dfs函数

}

int main(){

scanf("%d",&amp;n);

dfs(1);   //dfs函数的开始

return 0;

}

#include<stdio.h>

int a[10],book[10],total;

//这里还有需要注意的地方C语言全局变量默认为0

void  dfs(int step){

int i;

if(step==10){

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 ;  

}                

 for(int i=1;i<=9;i++){

if(book[i]==0){  //说明i号扑克牌还在手里,需要放入step号盒子

a[step]=i;//将i号扑克牌放到第step个盒子中

book[i]=1;//此时i号扑克牌已经被使用                

dfs(step+1);

/*注意这里是自己调用自己,表示此时走到了第step+1个盒子面前*/                

book[i]=0;

/*book[i]=0表示dfs调用结束了,换句话说就是扑克牌已经全部放完了

  需要按照顺序将扑克牌收回,重新放,也就是前面所说的

 */

}

}

return;//这里表示这一级别的dfs函数已经结束了,返回上一级 dfs函数

}

int main(){

dfs(1);   //dfs函数的开始

printf("%d",total/2);

return 0;

}

#include<stdio.h>

int book[51][51],a[51][51];

int n,m,p,q,min=99999;

int next[4][2]={

                                     {0,1}, //向右走一步

{1,0},//向下走一步

{0,-1},//向左走一步

{-1,0}};//向上走一步

void dfs(int x,int y,int step){   //step用来表示找到小红,小明走了多少步

int tx,ty,k;

if(x==p&amp;&amp; y==q){  //说明已经找到了小红 

/*

还要说明一点:这里 为什么是(x,y),而不是(tx,xy)

其实很简单 就是上一个dfs()函数传过来的坐标 ,做了这个dfs()函数的形参

换句话说:就是判断点是否找到小红

*/

if(step<min)

min=step;

return ;  

/*返回上一步,继续寻找其他路径(就是退回到上一个坐标,重新找其他路径)

   回到上一个dfs()函数

*/

}

for(k=0;k<=3;k++){   //下一步的坐标

tx=x+next[k][0];

ty=y+next[k][1];

//判断是否越界,越界则重新进入for循环

if(tx<1 || tx>n || ty<1 || ty>m)

continue; 

//运行到这里,说明这条路,则需要换个方向,也就是重新进入for循环

if(a[tx][ty]==0 &amp;&amp; book[tx][ty]==0){

book[tx][ty]=1; //标记这个点走过

dfs(tx,ty,step+1); //进行下一步

book[tx][ty]=0;   //重新尝试,退回到上一个点的位置

}

}

return ;   //执行到这里,这层dfs()函数已经结束,则要回到上一层dfs()函数

}

int main(){

int i,j,startx,starty;

scanf("%d %d",&amp;n,&amp;m);    //输入迷宫的大小

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

scanf("%d",&amp;a[i][j]);  //输入迷宫的形状

scanf("%d %d",&amp;startx,&amp;starty);  //小明的坐标

scanf("%d %d",&amp;p,&amp;q);            //小红的坐标

book[startx][starty]=1;         //起始点标记,就不会回到这个点了

dfs(startx,starty,0);      //开始寻找最短路径

printf("%d",min);        //输出最短路径

return 0;

}

如果有约束条件记得调整上下左右的顺序

  • 49
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HineMusk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值