• 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("
    ");
            }
    
        }
    
        return 0;
     } 
  • 相关阅读:
    SQL SERVER CXPACKET-Parallelism Wait Type 的惯用解决方案
    服务器主体 "sa" 无法在当前安全上下文下访问数据库 XXX[SQLSTATE 08004] (错误 916). 该步骤失败。
    Android 使用 aapt 命令查看 apk 包名
    Android数据库GreenDao的使用总结
    NestedScrollView、ScrollView 加载完自动滑动至底部问题的解决方案
    Android框架式编程之Retrofit
    Visual Studio 开发(三):Visual Studio 使用时常见问题解决方案
    Android 网络交互之移动端与服务端的加密处理
    Android框架式编程之ViewModel
    Android框架式编程之LiveData
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7350131.html
Copyright © 2020-2023  润新知