对于走迷宫的问题,具体的解题思想就是:从迷宫入口处发,沿着某一个方向试探,若是通路则往前走;否则,沿原路退回,再换一个方向继续试探,直到所有可能的通路都被试探过。而为了保证碰到死路能够正确的退回,就需要设一个栈结构来保存所走过的路径。
为了简化问题,迷宫可以用一个m*n的二维数组表示,1为道路阻塞,0为可进入。
对于每个位置,并非都有8个方向可走。所以在迷宫最外面套上一圈都为1的元素,保证每个位置都有8个方向。然后,每个方向的坐标都可由当前坐标计算(程序中用一个move[8][2]的二维数组存储)。
对于每个位置,约定从正北方向开始试探,然后顺时针逐个试探。当选定一个可通的方向后,要把目前所在的位置及所选的方向记录下来,以便当往下走不通时能一步步退回来,并且退回来之后试探下一个方向。而且为了避免走回已经经过的点,可将走过的地方设置标记(不妨为2)。由上分析,所设的栈的一个元素应包括三个信息:当前行坐标,列坐标以及所选择的方向。(Stack[MaxNum-1][3])
具体算法:
#define MaxN 100
#define MaxMN 10000
int MazePath( int Maze[][MaxN] , int m , int n) ...{
int Stack[MaxMN][3];
int move[8][2]=...{...{-1,0},...{-1,1},...{0,1},...{1,1},...{1,0},...{1,-1},...{0,-1},...{-1,-1}};
int p,i,j,k,g,h,top=0;
Maze[1][1]=2;
Stack[0][0]=1;
Stack[0][1]=1;
Stack[0][2]=1;
while(top>=0)...{
i=Stack[top][0];
j=Stack[top][1];
k=Stack[top--][2]+1;
while(k<8)...{
g=i+move[k][0];
h=j+move[k][1];
if(g==m-2&&h==n-2&&Maze[g][h]==0)...{
printf(" 找到一条出路! ");
for(p=0;p<=top;p++)
printf("%3d %3d",Stack[p][0],Stack[p][1]);
printf("%3d %3d",i,j);
printf("%3d %3d",m-1,n-1);
return 1;
}
if(Maze[g][h]==0)...{
Maze[g][h]=2;
Stack[++top][0]=i;
Stack[top][1]=j;
Stack[top][2]=k;
i=g; j=h; k=0;
}
else k++;
}
}
printf(" 迷宫中没有发现出路 ");
return 0;
}
#define MaxMN 10000
int MazePath( int Maze[][MaxN] , int m , int n) ...{
int Stack[MaxMN][3];
int move[8][2]=...{...{-1,0},...{-1,1},...{0,1},...{1,1},...{1,0},...{1,-1},...{0,-1},...{-1,-1}};
int p,i,j,k,g,h,top=0;
Maze[1][1]=2;
Stack[0][0]=1;
Stack[0][1]=1;
Stack[0][2]=1;
while(top>=0)...{
i=Stack[top][0];
j=Stack[top][1];
k=Stack[top--][2]+1;
while(k<8)...{
g=i+move[k][0];
h=j+move[k][1];
if(g==m-2&&h==n-2&&Maze[g][h]==0)...{
printf(" 找到一条出路! ");
for(p=0;p<=top;p++)
printf("%3d %3d",Stack[p][0],Stack[p][1]);
printf("%3d %3d",i,j);
printf("%3d %3d",m-1,n-1);
return 1;
}
if(Maze[g][h]==0)...{
Maze[g][h]=2;
Stack[++top][0]=i;
Stack[top][1]=j;
Stack[top][2]=k;
i=g; j=h; k=0;
}
else k++;
}
}
printf(" 迷宫中没有发现出路 ");
return 0;
}