转载请注明出处,谢谢~
背景说明:
老鼠走迷宫是递回求解的基本问题,我们在二维阵列中用2表示迷宫墙壁,使用1来表示老鼠走过的路径,求出由入口到出口的路径。
大天朝白话文:
有迷宫挡在了你和妹子/帅哥中间,自己看着办吧。
首先打印个小迷宫看看:
全封闭?No!我们去掉最右边和最底下的一行,只要这个7*7方阵,外边包起来主要是看路径的时候比较清晰。
把左上角的第一个非墙壁点作为起点,即二维数组的(1,1)元素作为起点,赋值为0,整个数组可以定义为:
int maze[9][9] = {
{2,2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,2,0,0,2},
{2,0,2,0,2,0,2,0,2},
{2,0,0,0,0,0,2,0,2},
{2,2,0,2,2,0,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,2,2,2,2,2,2,2,2}
};
然后我们脑补画面,一个小老鼠往下走,他有四个方向可以选择,上下左右,右边和下边是空的,可以移动,移动后又有四个方向可以选择,做判断,如果不是墙壁2,则可以移动,以此类推,知道移动到终点(7,7)的位置,打印路径即可,移动过的地方我们赋值为1,直到走到终点,然后递回的过程把上一个多选位置(即至少有两个方向可走)到下一个多选位置的元素全部置回0.下面就是代码实现:
void visit(int i,int j)
{
int m,n;
maze[i][j] = 1;
if (i == endI && j == endJ)
{
printf("\n显示路径: \n");
for (m = 0 ; m < 9 ; m++)
{
for (n = 0 ; n<9 ; n++)
{
if(maze[m][n] == 2){
printf("█");
}else if(maze[m][n] == 1)
printf("◇");
else
printf(" ");
}
printf("\n");
}
}
if(maze[i][j+1] == 0) visit(i, j+1);
if(maze[i+1][j] == 0) visit(i+1, j);
if(maze[i][j-1] == 0) visit(i, j-1);
if(maze[i-1][j] == 0) visit(i-1, j);
maze[i][j] = 0;
}
附上完整代码:
#include
#include
void visit(int ,int);
int maze[9][9] = {
{2,2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,2,0,0,2},
{2,0,2,0,2,0,2,0,2},
{2,0,0,0,0,0,2,0,2},
{2,2,0,2,2,0,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,2,2,2,2,2,2,2,2}
};
int startI = 1,startJ = 1;
int endI = 7,endJ = 7;
int main(void)
{
int i,j;
printf("显示迷宫 :\n");
for (i = 0 ; i < 9 ; i++)
{
for (j = 0 ; j < 9 ; j++)
{
if(maze[i][j] == 2){
printf("▉");
}else{
printf(" ");
}
}
printf("\n");
}
visit(startI,startJ);
system("pause");
return 0;
}
void visit(int i,int j)
{
int m,n;
maze[i][j] = 1;
if (i == endI && j == endJ)
{
printf("\n显示路径: \n");
for (m = 0 ; m < 9 ; m++)
{
for (n = 0 ; n<9 ; n++)
{
if(maze[m][n] == 2){
printf("█");
}else if(maze[m][n] == 1)
printf("◇");
else
printf(" ");
}
printf("\n");
}
}
if(maze[i][j+1] == 0) visit(i, j+1);
if(maze[i+1][j] == 0) visit(i+1, j);
if(maze[i][j-1] == 0) visit(i, j-1);
if(maze[i-1][j] == 0) visit(i-1, j);
maze[i][j] = 0;
}
但是有些时候我们不希望打印所有的路径,而只希望打印一条路径即可,那么我们修改下代码:
int visit2(int i, int j) {
maze[i][j] = 1;
if(i == endI && j == endJ)
success = 1;
if(success != 1 && maze[i][j+1] == 0) visit(i, j+1);
if(success != 1 && maze[i+1][j] == 0) visit(i+1, j);
if(success != 1 && maze[i][j-1] == 0) visit(i, j-1);
if(success != 1 && maze[i-1][j] == 0) visit(i-1, j);
if(success != 1)
maze[i][j] = 0;
return success;
}
visit2的作用就成了找到一条可用路径即可。下面附上main的代码:
int main(void) {
int i, j;
printf("\n");
for(i = 0; i < 7; i++) {
for(j = 0; j < 7; j++)
if(maze[i][j] == 2)
printf("█");
else
printf(" ");
printf("\n");
}
if(visit2(startI, startJ) == 0)
printf("");
else {
printf("\ng\n");
for(i = 0; i < 7; i++) {
for(j = 0; j < 7; j++) {
if(maze[i][j] == 2)
printf("█");
else if(maze[i][j] == 1)
printf(" ");
else
printf(" ");
}
printf("\n");
}
}
return 0;
}