• 跳跳 一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。


    我写的博客都是用c语言写的,易懂,重在理解

    在做这道题的时候,我很无奈,看着别人做,自己却没思路,很无奈,In a word,一句话,是没有理解好bfs的后果

    bfs相当于在头点,上下左右,寻找能走的路,最终以找到终点为目地。

    bfs相当于二叉树中的层次遍历,需要用到栈

     一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。

    Input

     每组数据第一行一个n,表示尺寸,2 <= n <= 100。

    接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。

    Output

     每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。

    如果无法到达重点,输出"Oh No!"

    5
    0S100
    00131
    00300
    00000
    003E0
    3
    S12
    010
    10E

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <string.h>
    #define N 110
    using namespace std;

    int vis[N][N], dis[N][N],a[N][N];
    int n,x1,y1,x2,y2;
    int dx[4]= {1,-1,0,0};
    int dy[4]= {0,0,1,-1};
    void bfs(int x3,int y3,int x2,int y2)
    {

    queue <pair<int ,int > >q; // 这是用的STL中的队列和pair,pair< 存类型>
    q.push(make_pair(x3,y3)); // 把坐标放通过pair对,放进队列

    vis[x3][y3]=1;   //访问过标记一下

    while(!q.empty())
    {

    int x1,y1;
    x1=q.front().first;   // 取出队列中一组pair对的横坐标

    y1=q.front().second; // 取出队列中一组pair对的纵坐标
    if(x1==x2&&y1==y2)break;  

    q.pop();  //清空队列头元素

    int i;
    for(i=0; i<4; i++)
    {

    int xx,yy;
    xx=x1+dx[i];
    yy=y1+dy[i];

    if(vis[xx][yy]==0&&a[xx][yy]==0) 
    {
    vis[xx][yy]=1;
    q.push(make_pair(xx,yy));
    dis[xx][yy]=1+dis[x1][y1];  // 记录当前层数,即当前步数
    }
    else if(a[xx][yy]>=2&&a[xx][yy]<=9&&vis[xx][yy]==0)  //假如碰到2和9之间的数x,就把此图中的x全部进入队列
    {

    vis[xx][yy]=1;
    q.push(make_pair(xx,yy));   
    dis[xx][yy]=1+dis[x1][y1];  记录步数

    for(int i=1; i<=n; i++)
    for(int j=1; j<=n; j++)
    if(a[i][j]==a[xx][yy]&&vis[i][j]==0)
    {
    q.push(make_pair(i,j));   
    vis[i][j]=1;
    dis[i][j]=dis[xx][yy];  // 因为题目说移到相同数字的方块,不耗费时间,所以不加1
    }

    }

    }

    }
    }
    int main()
    {
    while(scanf("%d",&n)!=EOF)
    {
    int i,j;
    char s[120];
    memset(vis,0,sizeof(vis));   //标记是否被访问过
    memset(a,1,sizeof(a));    // 转化为迷宫问题
    memset(dis,0,sizeof(dis));  // 储存二叉树的层数,即最小的步数到达终点
    for(i=0; i<n; i++)
    {
    scanf("%s",s);
    for(j=0; j<n; j++)
    {
    if(s[j]=='0')a[i+1][j+1]=0;
    else if(s[j]>='2'&&s[j]<='9')a[i+1][j+1]=s[j]-'0';   
    else if(s[j]=='S')a[i+1][j+1]=0,x1=i+1,y1=j+1;     //处理字符串,把a建成平面图
    else if(s[j]=='E')a[i+1][j+1]=0,x2=i+1,y2=j+1;

    }
    }

    bfs(x1,y1,x2,y2);
    if(dis[x2][y2]==0)printf("Oh No! ");  //如果不能到达终点,则储存路径的数组中为初始值0
    else printf("%d ",dis[x2][y2]);
    }

    }

  • 相关阅读:
    延迟任务
    xxl-job 执行器调度
    Linux查看日志定位问题
    docker 远程连接
    sqlserver的备份和恢复 命令非计划任务
    创建带包含列的索引 sqlserver
    exec sp_executesql (sqlsugar使用中的坑)的坑。执行sql非常慢
    vue elementui的表单设计器
    将docker容器的配置导出为docker-compose.yml
    异步通信,rpc通信的笔记
  • 原文地址:https://www.cnblogs.com/woyaocheng/p/4725237.html
Copyright © 2020-2023  润新知