C语言的迷宫问题及迷宫进阶

 萌新一个,有问题大家可以一起在评论下学习交流,不用互杠,没必要,你杠就是你对,和谐相处,共建程序猿美好世界。

1.迷宫问题

链接:迷宫问题__牛客网
来源:牛客网

[编程题]迷宫问题

定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一格是可以走的路。

注:1.这里给出的迷宫的出路有且仅有一条,迷宫进阶中会涉及多条出路

       2.C语言中没有相应的栈,队列等库使用,需手动实现栈

      

首先我的思路如下:

1)动态开辟二维数组,存储输入的值(记得内存释放:先释放一维后释放二维,避免内存泄漏),牛客网的测试用例一次可能会给多个,所以我们可以用while语句判断scanf输入的是否为最后一个(EOF)。

 

打完后可以写个函数测试一下迷宫是否出来了(有的时候牛客网的系统会有点问题,多提交几次就会出现输出)

2)定义坐标结构体,确定终点路线通过坐标上下左右递归遍历(遍历顺序根据个人喜好,对算法效率没什么大作用,因为这里给出的迷宫是不定的)

  

先判断它上下左右是否为通路再进行递归遍历,设置函数返回值确定回溯标志,若各个方向都为死路,则返回false。

 

嘿嘿,是不是觉得还差点什么

是的,为了避免走过的路不被再次走,需给走过的坐标标记除0以外的值(因为0为通路)

找到出口,结束递归

3)最后一步,存储坐标并打印坐标(选用栈存储坐标,后进先出,使用栈时,一定要初始化,栈用完要销毁)

首先在遍历之前先将坐标点入栈

在各方向遍历后,此坐标点不通则出栈 

顺序打印路径(因为是栈,为了顺序打印栈,我们要进行倒栈)

 

 最后测试一下就好啦!

最后,全部代码奉上

 

2.迷宫进阶:在基础的迷宫问题上,增加了多条路径求最短,及体力值的限定条件

链接:地下迷宫_滴滴笔试题_牛客网
来源:牛客网

小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。

输入描述:

输入包括n+1行:

第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100)

接下来的n行: 每行m个0或者1,以空格分隔

输出描述:

如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;如果不能逃离迷宫,则输出"Can not escape!"。 测试数据保证答案唯一

注:1.这里1为通路,0为墙

     2.初始点不变,但出口在(0,m-1)

     3.为了巩固自己,不复制之前的迷宫,可以自己试着把基础迷宫问题实现

具体进阶思路如下:

1.将判断通路函数的条件和判断出口的条件修改

  

2.增加体力值参数P,遍历时,根据方向不同,消耗体力值也不一样。

   因为涉及多条路求最短,所以不能设返回值。

遍历完第一条路后,则要将坐标设回为通路,否则通路将只有一条,就像这样(字有点丑,不过那不是重点哈)

3.增加一个新的栈(初始化+释放)存储最短路径

 

到达终点且体力值>=0时才更新最短路径,否则最短路径不变

这里涉及浅拷贝和深拷贝的知识

我们用深拷贝能够避免内存泄漏,又因为修改同一个指针,容易造成数据混乱,所以我们先释放原来存储最短路径的栈,重新建一个栈并将更新后的栈的坐标及容量赋值给它,这样就实现了深拷贝。

代码如下:

最后打印最短路径,整个实现就完成了!

迷宫进阶的全部代码如下

学废了吗?以上就是本人学习迷宫求解的路程,历时俩天,欢迎小伙伴们点评不足,互相学习,共同进步呀~~~

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值