迷宫问题所有解:
//迷宫问题解答:
首先需要定义的变量:迷宫M , 迷宫的行R=7 , 迷宫的列C=8 , 还需要定义一个与迷宫M相同的二维数组t(用来表示迷宫这个格子已经走过了,走过赋值为1) , 以及记录方位的二维数组Move[4][2](f方位表示已经在代码中给出注释) , 定义一个栈stack[100][2](用来存储路径上的点横纵坐标);
//迷宫问题需要注意的点:
1.首先需要注意的是:记录走过格子的数组t,最主要的作用是防止迷宫绕圈走;
比如:
2.栈在迷宫中的作用:
1>首先判断这个路径可不可以走,需要两个条件:
1) 第一:给定的迷宫数组M所对点的数值为 0;
2) 第二:记录走过的路径二维数组t所对应的数值为 0;
2>可以走的话,先将数组 M 和 t 所对应位置的值赋1;
3>给记录栈顶的 top++ ,之后将这个位置的横纵坐标分别赋给栈:stack[top][0]=a,stack[top][1]=b;
4>之后进入递归进行下一个位置的判断,如此往复;
5>知道找到满足出口的条件,调用输出函数,输出一条迷宫的路径;
3.迷宫的回溯问题:
1) 如果这个位置,在判断完四个方向都不能找到下一个位置;
2) 当前整个迷宫函数Maze执行完,回到上一个函数的调用Maze函数的位置;
3) 所以需要清空当前数组 M 和数组 t 所对应位置的数值,给两个位置赋 0;
4) 之后还要将这个位置所对应的栈顶元素取出,即 top--;
5) 完成上述步骤,整个函数执行完,i++,继续判断下一个方向是否可以走,不能走回溯,能走就走,继续判断位置;
#include<zstdio.h>
#define R 7 //行;
#define C 8 //列;
int M[R+2][C+2]= //迷宫'1'表示墙,'0'表示路;
{
//0 1 2 3 4 5 6 7 8 9
/*0*/1,1,1,1,1,1,1,1,1,1,
/*1*/1,0,0,0,1,1,1,1,1,1,
/*2*/1,0,1,0,1,1,1,1,1,1,
/*3*/1,0,0,0,1,1,1,1,1,1,
/*4*/1,1,1,0,0,0,0,1,1,1,
/*5*/1,1,1,1,0,1,1,1,1,1,
/*6*/1,1,1,1,0,0,0,1,1,1,
/*7*/1,1,1,1,1,1,0,0,0,1,
/*8*/1,1,1,1,1,1,1,1,1,1
};
int t[R+2][C+2]={0}; //与迷宫相同的二维数组,用来表示该条路有没有走;
int Move[4][2]= //记录走的方向;
{
{1,0}, //向南走;
{0,1}, //向东走;
{-1,0}, //向北走;
{0,-1} //向西走;
};
int stack[100][2]; //用来存放路径的栈;
int top;
int sum=0;
//输出;
void Print(int sum)
{
printf("迷宫的第%d条路径如下:\n",sum);
for(int i=0;i<=top;i++)
printf("(%d,%d)->",stack[i][0],stack[i][1]);
printf("出口");
printf("\n");
}
//调用迷宫函数;
void Maze(int x,int y)
{
if(x==7&&y==8)
{
sum++;
Print(sum);
}
else
{
for(int i=0;i<4;i++) //遍历四个方向;
{
int a=x+Move[i][0]; //找到下一个要走位置的x;
int b=y+Move[i][1]; //找到下一个要走位置的y;
if(!M[a][b]&&!t[a][b]) //判断这个位置可不可以走;
{
t[a][b]=M[a][b]=1; //用数组t,M记录这个位置已经走过了;
top++; //将top++用来存储下一个位置坐标;
stack[top][0]=a; //将横坐标x存入stack数组中;
stack[top][1]=b; //将纵坐标y存入stack数组中;
Maze(a,b); //继续寻找下一个位置;
t[a][b]=M[a][b]=0; //回溯之后需要将这个位置清空,表示这条路没有走过;
top--; //并且将这个位置从栈中去除;
}
}
}
}
int main(void)
{
//迷宫初始化;
stack[0][0]=1; //存放起点的x,y的坐标;
stack[0][1]=1;
top=0; //top++表示已经存放了开始坐标;
t[1][1]=M[1][1]=1; //表示第一个位置已经走过了;
Maze(1,1);
return 0;
}
//结果截图: