codeup 1742: 算法3-3:迷宫
题目描述
有一个 10 x 10 的迷宫,起点是‘S’,终点是‘E’,墙是‘#’,道路是空格。一个机器人从起点走到终点。当机器人走到一个通道块,前面已经没有路可走时,它会转向到当前面向的右手方向继续走。如果机器人能够过,则留下足迹‘*’,如果走不通,则留下标记‘!’。
下面给出书中的算法,请你模拟机器人的走法输出最终的状态。
图:迷宫算法
输入
一个 10 x 10 的二维字符数组。
输出
机器人走过的路径状态。
样例输入
##########
#S # # #
# # # #
# ## #
# ### #
# # #
# # # #
# ### ## #
## E#
##########
样例输出
##########
#**#!!!# #
# *#!!!# #
#**!!## #
#*### #
#***# #
# #***# #
# ###*## #
## ****#
##########
注意点:
- —方向是顺时针进行探索
- — 在s->top++中,用括号(s->top)++,优先级的问题,已经被这个点坑了两次了
其余没什么好说的,具体的步骤已经写在注释里
#include<stdio.h>
#include<stdlib.h>
#define N 10
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define ERROR 0
#define OK 1
char maze[N+10][N+10];
typedef int Status;
typedef struct{
int x;
int y;
}PosType;
typedef struct{
int ord;//步数
PosType seat;//坐标位置
int di;//方向
}SElemType;
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
Status InitStack(SqStack *s)
{//初始化栈
s->base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!s->base )
return ERROR;
s->top = s->base ;
s->stacksize = STACK_INIT_SIZE;
return OK;
}
Status Pass(char maze[][N+10],PosType *s)
{//判断是否可以通过
if(maze[s->x][s->y]==' '||maze[s->x][s->y]=='S'||maze[s->x][s->y] == 'E')
return OK;
else
return ERROR;
}
void FootPrint(char maze[][N+10],PosType *s)
{//留下能够通过的标记
maze[s->x ][s->y ] = '*';
}
Status Push(SqStack *s,SElemType *e)
{//入栈
SElemType *newbase;
if( (s->top-s->base )>= s->stacksize )
{
newbase = (SElemType*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!newbase)
return ERROR;
s->base = newbase;
s->stacksize += STACKINCREMENT;
}
*(s->top)++= *e;
return OK;
}
Status Pop(SqStack *s,SElemType *e)
{//出栈
if(s->base == s->top )
return ERROR;
*e = *--(s->top);
return OK;
}
PosType NextPose(PosType *s,int i)
{//更新位置
if(i == 1)
s->y = s->y +1;
else if(i == 2)
s->x = s->x +1;
else if( i == 3)
s->y = s->y -1;
else
s->x = s->x -1;
return *s;
}
Status EmptyStack(SqStack *s)
{//判断是否为空
if(s->base == s->top )
return OK;
return ERROR;
}
void MarkPrint(char maze[][N+10],PosType *s)
{
maze[s->x ][s->y] = '!';
}
Status MazePath(char maze[][N+10],PosType start,PosType end)
{
//算法3.3
//若迷宫maze中存在从入口start到出口end的通道,则求得一条存放在栈中,并返回OK ,否则返回ERROR
SqStack s;
InitStack(&s);
PosType curpos = start;//设定当前位置为入口位置
SElemType e;
int curstep = 1;//探索第一步
do{
if(Pass(maze,&curpos))//当前位置可以通过
{
FootPrint(maze,&curpos);//留下足迹
e.di = 1;
e.ord = curstep;
e.seat = curpos;
Push(&s,&e);//加入路径
if(curpos.x == end.x &&curpos.y == end.y )
{
return OK;//到达终点
}
curpos = NextPose(&curpos,e.di );//下一个位置是当前位置的东邻
curstep ++;//探索下一步
}
else
{//当前位置不能通过
if(!EmptyStack(&s))
{
Pop(&s,&e);
while(e.di == 4&&!EmptyStack(&s))
{
MarkPrint(maze,&e.seat);//留下不能通过的标记
Pop(&s,&e);//退回一步
}
if(e.di < 4)
{
e.di ++;
Push(&s,&e);//换下一个方向
curpos = NextPose(&e.seat,e.di);//当前位置为新方向的相邻块
}
}
}
}while(!EmptyStack(&s));
}
int main()
{
int i,j;
PosType start,end;
for( i = 0; i < 10; i ++)
{
for( j = 0; j <10; j ++)
{
scanf("%c",&maze[i][j]);
if(maze[i][j] == 'S')
{
start.x = i;
start.y = j;
}
if(maze[i][j] == 'E')
{
end.x = i;
end.y = j;
}
}
getchar();
}
if(MazePath(maze,start,end))
{
for( i = 0; i < 10; i ++)
{
for( j = 0; j <10; j ++)
printf("%c",maze[i][j]);
printf("\n");
}
}
return 0;
}