萌新一个,有问题大家可以一起在评论下学习交流,不用互杠,没必要,你杠就是你对,和谐相处,共建程序猿美好世界。
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时才更新最短路径,否则最短路径不变
这里涉及浅拷贝和深拷贝的知识
我们用深拷贝能够避免内存泄漏,又因为修改同一个指针,容易造成数据混乱,所以我们先释放原来存储最短路径的栈,重新建一个栈并将更新后的栈的坐标及容量赋值给它,这样就实现了深拷贝。
代码如下:
最后打印最短路径,整个实现就完成了!
迷宫进阶的全部代码如下
学废了吗?以上就是本人学习迷宫求解的路程,历时俩天,欢迎小伙伴们点评不足,互相学习,共同进步呀~~~