zoukankan      html  css  js  c++  java
  • 小A与小B-(双向bfs)

    链接:https://ac.nowcoder.com/acm/contest/549/G
    来源:牛客网

    题目描述

    小A与小B这次两个人都被困在了迷宫里面的两个不同的位置,而他们希望能够迅速找到对方,然后再考虑如何逃离迷宫的事情。小A每次可以移动一个位置,而小B每次可以移动两次位置,小A移动的方向是上下左右左上左下右上右下8个方向,小B移动的方向是上下左右4个方向,请问他们最早什么时候能够找到对方,如果他们最终无法相遇,那么就输出”NO"。

    输入描述:

    NMN×M"C"A,"D"B"""."第一行两个整数N,M分别表示迷宫的行和列。接下来一个N×M的矩阵其中"C"表示小A的位置,"D"表示小B的的位置,"#"表示不可通过的障碍,"."则是可以正常通过的位置。字符用空格隔开

    输出描述:

    如果可以相遇,第一行输出一个YES,第二行一个整数输出最短的相遇时间。
    否则就输出一个NO表示不能相遇。
    示例1

    输入

    4 5
    . . . . .
    . # # # .
    . . . # D
    . . C # .
    

    输出

    YES
    3

    备注:

    1n,m1000

    解题:
    首次遇到地图里两个人的,显然用两次bfs,而且其中一个人不是简简单单每次走一步,而是每次走两步,个人感觉变动有点大,驾驭不住,就写了两个bfs函数,我看大牛们一个就够了,用参数解决。
    用三维数组表示不同人的走路步数,一边判断是否走过,顺便标记步数。
    最后遍历地图,取二者都能走到的位置,取二人步数大者为答案,动态找较大者的最小值。
      1 #include<stdio.h>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<math.h>
      6 #include<string>
      7 #include<queue>
      8 #define ll long long
      9 #define inf 0x3f3f3f3f
     10 using namespace std;
     11 
     12 struct node
     13 {
     14     int x;
     15     int y;
     16 };
     17 int n,m,ans;
     18 int ax,ay,bx,by,cnt;
     19 char mp[1005][1005];
     20 int vis[2][1005][1005];///判断是否走过,顺便记录走到这一步的步数
     21 int d0[8][2]={-1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1};///A的位移
     22 int d1[4][2]={-1,0, 1,0, 0,-1, 0,1};///B的位移
     23 queue<node>que[2];///0表示A,1表示B
     24 
     25 void bfs0()
     26 {
     27     while(!que[0].empty()) que[0].pop();
     28     que[0].push( {ax,ay} );
     29     while(!que[0].empty())
     30     {
     31         node now=que[0].front();
     32         int cnt=vis[0][now.x][now.y];///走到这一步的步数
     33         que[0].pop();
     34         for(int i=0;i<8;i++)
     35         {
     36             int xx=now.x+d0[i][0];
     37             int yy=now.y+d0[i][1];
     38             if( xx>=1 && xx<=n && yy>=1 && yy<=m && mp[xx][yy]=='.' && vis[0][xx][yy]==-1 )
     39             {
     40                 que[0].push( {xx,yy} );
     41                 vis[0][xx][yy]=cnt+1;///位移+1
     42             }
     43         }
     44     }
     45 }
     46 
     47 void bfs1()
     48 {
     49     while(!que[1].empty()) que[1].pop();
     50     que[1].push( {bx,by} );
     51     while(!que[1].empty())
     52     {
     53         node now=que[1].front();
     54         que[1].pop();
     55         int cnt=vis[1][now.x][now.y];
     56         for(int i=0;i<4;i++)///第一步
     57         {
     58             int xx=now.x+d1[i][0];
     59             int yy=now.y+d1[i][1];
     60             if(xx>=1 && xx<=n && yy>=1 && yy<=m && mp[xx][yy]=='.' && vis[1][xx][yy]==-1 )
     61             {
     62                 vis[1][xx][yy]=cnt+1;///第一步也要记录位移次数,与第二步的次数一样
     63                 for(int j=0;j<4;j++)///第二步在if大括号里,否则会窗墙
     64                 {
     65                     int tx=xx+d1[j][0];
     66                     int ty=yy+d1[j][1];
     67 
     68                     if( tx>=1 && tx<=n && ty>=1 && ty<=m && mp[tx][ty]=='.' && vis[1][tx][ty]==-1 )
     69                     {
     70                         que[1].push( {tx,ty} );
     71                         vis[1][tx][ty]=cnt+1;///位移次数+1
     72                     }
     73                 }
     74             }
     75         }
     76     }
     77 }
     78 
     79 
     80 int main()
     81 {
     82     memset(vis,-1,sizeof(vis));
     83     scanf("%d %d",&n,&m);
     84     for(int i=1;i<=n;i++)
     85         for(int j=1;j<=m;j++)
     86     {
     87         cin>>mp[i][j];
     88         if(mp[i][j]=='C') ax=i,ay=j;
     89         if(mp[i][j]=='D') bx=i,by=j;
     90     }
     91     vis[0][ax][ay]=0;
     92     vis[1][bx][by]=0;///起点为0
     93     bfs0();
     94     bfs1();
     95 /**打印观察
     96     for(int i=1;i<=n;i++)
     97     {
     98         for(int j=1;j<=m;j++)
     99         printf("%2d ",vis[0][i][j]);
    100         printf("
    ");
    101     }
    102     printf("
    
    ");
    103     for(int i=1;i<=n;i++)
    104     {
    105         for(int j=1;j<=m;j++)
    106         printf("%2d ",vis[1][i][j]);
    107         printf("
    ");
    108     }
    109 */
    110     int ans=inf;
    111     for(int i=1;i<=n;i++)
    112         for(int j=1;j<=m;j++)
    113     {
    114         if( vis[0][i][j]!=-1 && vis[1][i][j]!=-1 )
    115             ans = min( max(vis[0][i][j],vis[1][i][j]), ans );
    116     }
    117     if(ans!=inf)
    118         printf("YES
    %d
    ",ans);
    119     else
    120         printf("NO
    ");
    121     return 0;
    122 }


  • 相关阅读:
    iOS商品详情、ffmpeg播放器、指示器集锦、自定义圆弧菜单、实用工具等源码
    android愤怒小鸟游戏、自定义View、掌上餐厅App、OpenGL自定义气泡、抖音电影滤镜效果等源码
    iOS渐变视图&动画库、腰杆、音频水滴水波手势、多种对话框、四级展开效果等源码
    android应用市场、社区客户端、漫画App、TensorFlow Demo、歌词显示、动画效果等源码
    iOS炫酷动画图案、多种选择器、网络测速、滑动卡片效果等源码
    android多框架实现短视频应用、3D手势旋转、banner控件、指南针、智能管家等应用源码
    iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码
    android完整资讯App、Kotlin新闻应用MVP + RxJava + Retrofit + Dagger2、优雅区间选择器等源码
    iOS运营级B2B服务平台App、自定义图标库、个人中心页面、识别身份证Demo、瀑布流等源码
    Flutter中的浮动按钮 FloatingActionButton
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10701620.html
Copyright © 2011-2022 走看看