zoukankan      html  css  js  c++  java
  • 迷宫问题

    问题 E: 迷宫问题

    时间限制: 1 Sec  内存限制: 32 MB
    提交: 1452  解决: 518
    [提交][状态][讨论版]

    题目描述

    小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。
    小明只能向上下左右四个方向移动。

    输入

    输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。
    每组输入的第一行是两个整数N和M(1<=N,M<=100)。
    接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。
    字符的含义如下:
    ‘S’:起点
    ‘E’:终点
    ‘-’:空地,可以通过
    ‘#’:障碍,无法通过
    输入数据保证有且仅有一个起点和终点。

    输出

    对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。

    样例输入

    1
    5 5
    S-###
    -----
    ##---
    E#---
    ---##

    样例输出

    9
    思路:
    广度优先遍历
    #include<stdio.h>
    #include<string.h>
    #define N 110
    int book[N][N];
    char str[N][N];
    int n,m;
    int next[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//表示方向
    int sx,sy,ex,ey;
    int t;
    int tx,ty;
    int head,tail,flag;
    int i,j;
    struct note {
        int x;//横坐标 
        int y;//纵坐标 
        int s;//记录步数 
    };
    struct note que[N*N];//拓展队列不能超过N*N 
    
    int main()
    {
        scanf("%d",&t);
        while( t --)
        {
            scanf("%d%d",&n,&m);
            getchar();
            memset(book,0,sizeof(book));
            for(i = 1; i <= n; i ++)
            {
                for(j = 1; j <= m; j ++)
                {
                    scanf("%c",&str[i][j]);
                    if(str[i][j] == 'S')//记录始末位置 
                    {
                        sx = i;
                        sy = j;
                    }
                    if(str[i][j] == 'E')
                    {
                        ex = i;
                        ey = j;
                    }
                }
                getchar();
            }
            book[sx][sy] = 1;
            //队列初始化 
            head = 1;
            tail = 1;
            flag = 0;//flag为0表示还没有到达目标点,1表示到达 
            //往队列插入迷宫的入口坐标 
            que[tail].x = sx;
            que[tail].y = sy;
            que[tail].s = 0;
            tail ++;
            //队列不为空的时候 
            while(head < tail)
            {
                //判断四个方向 
                for( i = 0; i < 4; i ++)
                {
                    //计算下一个坐标 
                    tx = que[head].x + next[i][0];
                    ty = que[head].y + next[i][1];
                    //判断是否越界 
                    if(tx < 1||tx > n||ty < 1||ty > m)
                        continue;
                    //如果没走过这个点并且没有障碍物 
                    if(!book[tx][ty]&&str[tx][ty]!='#')
                    {
                        //把这个点标记为已经走过 
                        book[tx][ty] = 1;
                        //插入新的点到队列 
                        que[tail].x = tx;
                        que[tail].y = ty;
                        //步数是父亲步数+1 
                        que[tail].s = que[head].s +1;
                        tail++;
                    }
                    //如果到目标点了,退出循环 
                    if(tx == ex&&ty == ey)
                    {
                        flag = 1;
                        break;
                    }
                }
                if(flag == 1)
                {
                    break;
                }
                //当一个点拓展完后,head++才能对后面的点进行拓展 
                head ++;
            }
            
            if(flag == 0)
                printf("-1
    ");
            else//注意tail指向队列队尾的下一个位置,所以需要-1 
                printf("%d
    ",que[tail-1].s);//打印队列中 末尾最后一个点的步数 
        }
        return 0;
    }
    
    
     
    
    
    
     
  • 相关阅读:
    JAVA8学习——Stream底层的实现三(学习过程)
    JAVA8学习——Stream底层的实现二(学习过程)
    JAVA8学习——Stream底层的实现一(学习过程)
    2020年的第一天-我的IDEA出现This license ... has been cancelled
    Java Applet与Java Application的区别
    Spring AOP 详解
    Spring中的代理(proxy)模式
    hibernate中查询方式(二):常用查询
    hibernate中查询方式(一):
    Spring(二)DI( Dependency Injection依赖注入)
  • 原文地址:https://www.cnblogs.com/yfr2zaz/p/11082713.html
Copyright © 2011-2022 走看看