zoukankan      html  css  js  c++  java
  • 电子老鼠闯迷宫(广搜_队列)_机器寻径引导(最短路径表)

    时限:1000ms 内存限制:10000K  总时限:3000ms

    描述:

    有一只电子老鼠被困在如下图所示的迷宫中。这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色部分是路。 电子老鼠可以在路上向上、下、左、右行走,每一步走一个格子。现给定一个起点S和一个终点T,求出电子老鼠最少 要几步从起点走到终点。

    输入:

    本题包含一个测例。在测例的第一行有四个由空格分隔的整数,分别表示起点的坐标S(x.y)和终点的坐标T(x,y)。 从第二行开始的12行中,每行有12个字符,描述迷宫的情况,其中'X'表示建筑物,'.'表示路.

    输出:

    输出一个整数,即电子老鼠走出迷宫至少需要的步数。

    输入样例:

    2 9 11 8
    XXXXXXXXXXXX
    X......X.XXX
    X.X.XX.....X
    X.X.XX.XXX.X
    X.X.....X..X
    X.XXXXXXXX.X
    X...X.X....X
    X.XXX...XXXX
    X.....X....X
    XXX.XXXX.X.X
    XXXXXXX..XXX
    XXXXXXXXXXXX

    输出样例:

    28

    #include<stdio.h>
    void readdata();
    void init();
    int  search();
    bool empty_queue();
    void addto_queue(int row,int col);
    int  takeout_queue();
    bool canmoveto(int row,int col,int *r,int *c,int i);
    bool isaim(int row,int col);
    
    #define N 12
    char Array[12][12];
    int beginrow,begincol,endrow,endcol;
    int head,tail,queue[1000],queue_len=1000;//广搜,使用队列
    int main()
    {
        int i,j;
        int step_num;
        readdata();
        init();
        //////输出初始状态
        printf("初始状态:\n");
        for(i=0;i<N;i++)
        {  
            for(j=0;j<N;j++)
            {
                printf("%2c",Array[i][j]);       
            }
            printf("\n");
        }
        //////
        step_num=search();
        printf("结束状态:\n");
        for(i=0;i<N;i++)//输出搜索之后的状态
        {  
            for(j=0;j<N;j++)
            {
                if(Array[i][j]=='*' ||Array[i][j]=='.')
                    printf("%3c",Array[i][j]);//char[][]既可用%c输出(字符)    
                else
                    printf("%3d",Array[i][j]-48);//也可用%d输出(数字)
            }
            printf("\n");
        }
        printf("%d\n",step_num);
        return 0;
    }
    
    //////////////////////////////////////////////
    int search()
    {
        int i;
        int u,row,col,r,c;
        int num;
        while(!empty_queue())
        {
             u=takeout_queue();
             row=u/N;  col=u%N;
             num=Array[row][col]-48;//字符到数字(路径长)
             for(i=0;i<4;i++)//四个方向,广搜
             {
                 if(canmoveto(row,col,&r,&c,i))
                 {
                     if(isaim(r,c))
                        return num+1;//返回最短路径长度
                     Array[r][c]=(num+48)+1;//(路径长)数字到字符(Array[][]是字符数组)
                     addto_queue(r,c);
                 }
             }
        }
        return 0;
    }
    bool empty_queue()
    {
        if(head==tail)
            return true; 
        return false;
    }
    int takeout_queue()
    {
       int u;
       u=queue[head++];
       head=head%queue_len;
       return u;
    }
    bool canmoveto(int row,int col,int *r,int *c,int i)//判断能否由当前位置有方向i移动到下一位置
    {
        int PresentRow=row;
        int PresentCol=col;
        switch(i)
        {
            case 0: col--; break;//
            case 1: row++; break;//
            case 2: col++; break;//
            case 3: row--; break;//
        }
        *r=row;
        *c=col;
        if(row>=0 &&col>=0 &&row<N &&col<N)
            if(Array[row][col]=='.' ||Array[*r][*c]>Array[PresentRow][PresentCol]+1)//该点未走过,或有更短路径过该点
                return true;
        return false;
    }
    bool isaim(int r,int c)
    {
        if(r==endrow-1 &&c==endcol-1)
            return true;
        return false;
    }
    void addto_queue(int row,int col)
    {
        int u;
        u=row*N+col;
        queue[tail++]=u;
        tail=tail%queue_len;
    }
    
    
    //////////////////////////////////////////////
    void readdata()
    {
        int i,j;
        char str[12];
            scanf("%d%d",&beginrow,&begincol);//起点坐标
            scanf("%d%d",&endrow,&endcol);//终点点坐标    
        for(i=0;i<N;i++)
        {
            scanf("%s",str);//迷宫布局
            //gets(str);
            for(j=0;j<N;j++)
            {
               if(str[j]=='.')
                   Array[i][j]='.';
               else 
                   Array[i][j]='*';
            }
        }
    }
    void init()
    {
       head=0;
       tail=1;
       queue[0]=beginrow*N +begincol;//队列初始情况(queue中元素值在区间0~11*12+11之间)
       Array[beginrow][begincol]=0+48;//初始位置置'0'
    }
    
    /*
    2 9 11 8
    XXXXXXXXXXXX
    X......X.XXX
    X.X.XX.....X
    X.X.XX.XXX.X
    X.X.....X..X
    X.XXXXXXXX.X
    X...X.X....X
    X.XXX...XXXX
    X.....X....X
    XXX.XXXX.X.X
    XXXXXXX..XXX
    XXXXXXXXXXXX
    初始状态:
     * * * * * * * * * * * *
     * . . . . . . * . * * *
     * . * . * * . . . 0 . *
     * . * . * * . * * * . *
     * . * . . . . . * . . *
     * . * * * * * * * * . *
     * . . . * . * . . . . *
     * . * * * . . . * * * *
     * . . . . . * . . . . *
     * * * . * * * * . * . *
     * * * * * * * . . * * *
     * * * * * * * * * * * *
    结束状态:
      *  *  *  *  *  *  *  *  *  *  *  *
      *  9  8  7  6  5  4  *  2  *  *  *
      * 10  *  8  *  *  3  2  1  0  1  *
      * 11  *  9  *  *  4  *  *  *  2  *
      * 12  *  8  7  6  5  6  *  4  3  *
      * 13  *  *  *  *  *  *  *  *  4  *
      * 14  .  .  * 12  *  8  7  6  5  *
      *  .  *  *  * 11 10  9  *  *  *  *
      *  .  . 14 13 12  * 10 11 12 13  *
      *  *  *  .  *  *  *  * 12  *  .  *
      *  *  *  *  *  *  *  . 13  *  *  *
      *  *  *  *  *  *  *  *  *  *  *  *
    14
    Press any key to continue
    */
  • 相关阅读:
    C# WinForm TextBox 作为密码输入框时,如何禁止密码查看器获取密码 ?
    .net 程序运行在不同框架版本下的支持配置(主要是.net4.0 与 .net2.0的兼容)
    比较C#的静态常量(const)和动态常量(static和readonly)
    Linux 本地yum源 、阿里yum源、163yum源的配置安装
    Mysql 单机数据库迁移几种方式
    sed中使用变量及变量中存在特殊字符‘/’处理
    Linux下安装zookeeper、配置zookeeper开机自启动
    MySQL 不同场景下的迁移方案(转载)
    配置YUM源出现Errno 14 Could not open/read repomd.xml 或者 "Couldn't open file /mnt/cdrom/repodata/repomd.xml" 错误的解决办法
    Docker安装Rabbitmq并实现挂载宿主机数据目录
  • 原文地址:https://www.cnblogs.com/IThaitian/p/2581759.html
Copyright © 2011-2022 走看看