迷宫寻路:老鼠如何找到奶酪
【前言(免责声明)】
各位看官,这个标题找AI取的,因为想不到什么好标题。
而这篇文章大篇幅是我自言自语,逻辑可能不是很清晰,因为我思维跳跃,会突然想到自己前面有问题或者漏了什么,然后折回去删删改改。
同时也会有大篇幅伪代码。
【问题描述】
在迷宫中放着一大块奶酪,一只老鼠在迷宫中。迷宫中有墙,老鼠如何绕开墙,找到奶酪? 图中所示黑色部分为墙,已知老鼠、奶酪、墙的坐标的情况下,编程输出老鼠的行进路线。

【编程任务】
编程输出从老鼠到奶酪的行进路线。
【分析思路】
1. 如何在 input.txt 中表达地图?
通过坐标。
第一行表示地图大小,这里用10*10,第二行老鼠的起始位置,第三行奶酪位置,第四行黑格子数量,其余行黑色格子坐标。
2. 怎么判断哪些地方可走?
黑色方格为不可走路线,记作1,白色方格为可走路线,记作0.
同时,为了避免老鼠来回走,需要用2记作老鼠走过的位置。
3. 怎么确定“吃到了奶酪”?
首先要确保程序读取了input.txt里面第三行奶酪的坐标位置
。&lt;/p&gt;&lt;div class="cnblogs_code"&gt;&lt;pre&gt;&lt;span style="color: #008080;" data-mce-style="color: #008080;"&gt;1 <span style="color: #0000FF;" data-mce-style="color: #0000ff;">if(mouse.x == targetX && mouse.y ==<span style="color: #000000;" data-mce-style="color: #000000;"> targetY){ 2 // 老鼠吃到奶酪,保存所有坐标输出 3 }else{ 4 // 继续执行代码 5 }
4. 用什么方式来代表“向上、向下、向左、向右”这四个动作的顺序?
WASD
W(上):行号+1,列号不变→(1,0);
A(左):行号不变,列号-1→(0,-1);
S(下):行号-1,列号不变→(-1,0);
D(右):行号不变,列号+1→(0,1);
因此,代码中我们需要有两个数组来表示坐标的偏移量。
为了确保老鼠撞墙后会掉头,因此需要一个可以记录WASD的量。
其实到了这里,我觉得差不多了,只要仔细写一下 dir==0 部分就可以了。
但是我忽然意识到栈是“后进先出”的。
so,pass
同时,我忽略了如何不让老鼠跑外面这一点。
并且, curr.x++ 这个逻辑也有问题。
Node &curr = s.stop(); 指的是老鼠当前站着的格子。
假设老鼠站在 (1, 1),程序执行了 curr.x++ ,老鼠还没动,但它脚下的坐标变成了 (2, 1)。
为了避免该问题,应该创建一个新变量来存储它。
5. 固定数值代表某个反向
写到这里我觉得有必要先固定死一些数值,避免自己想一出是一出。
curr.dir(WASD):
- W(上):行号+1,列号不变→(1,0);
- A(左):行号不变,列号-1→(0,-1);
- S(下):行号-1,列号不变→(-1,0);
- D(右):行号不变,列号+1→(0,1);
因此,代码中我们需要有两个数组来表示坐标的偏移量。
为了确保老鼠撞墙后会掉头,因此需要一个可以记录WASD的量。
1 struct Node{ 2 int x,y;//当前所在格子的坐标 3 int dir;//记录走到了 WASD 哪一个,清楚下一步走哪边 4 } 5 6 while(!s.empty){ 7 Node &curr = s.top();//看看现在位置 8 9 // 检查老鼠吃没吃到奶酪 10 if(curr.x == targetX && curr.y == targetY){ 11 print("吃到奶酪"); 12 break; 13 14 if(dir==0){ 15 // 移动位置,不论前面是否有路都执行 16 curr.x++; 17 }else if(curr.dir == 1){ 18 // 向下走 19 }else if(curr.dir == 2){ 20 // 向左走 21 } //以此类推 22 23 if (curr.dir == 4) { 24 s.pop(); // 当前格子四个方向都试过了,全是墙或走过的,彻底放弃这个格子 25 } 26 }
这么一看,它们逻辑相当相似,一套完整的if-else语句下来,坐标变动情况:
-
(1, 0) —— 向下
-
(0, 1) —— 向右
-
(-1, 0) —— 向上
-
(0, -1) —— 向左
那么有没有什么好办法打包起来呢?
数组!绝对的数组!我想不到比数组还好的方法!
将x所有变量放入dx[ ],将y所有变量放入dy[ ]不就game over了?
当 curr.dir == 0 时, dx[0]==1,dy[0]==0 , 坐标为(1,0);
当 curr.dir == 1 时, dx[1]==0,dy[1]==1 , 坐标为(0,1);
......
有了它,我就可以省去if-else语句。
7. 处理“后进先出”问题
第一步:定义一个足够大的数组放栈
第二步:倒着打印数组
这个时候, path[0] 是终点, path[count-1] 是起点。
【实验代码】
【数据测试1】

【测试数据2】


浙公网安备 33010602011771号