• 一本通之 一堆迷宫 (Dungeon Master&走出迷宫&走迷宫)


    一本通在线崩溃.......

    有图有真相

    这是个三维迷宫,其实和二位迷宫差不多,只是方向多加了2个。

    但这个题的输入十分恶心,一度被坑的用cin.ignore(),但还是不过...

    它的正确输入方式是这样的

    while(scanf("%d%d%d",&n,&m,&s))
        {
         if(n==0&&m==0&&s==0)break;
           for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              scanf("%s",a[i][j]);
            }
            for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              {for(int k=0;k<s;k++)
               {if(a[i][j][k]=='S')
                 {sx=i;sy=j;sz=k;
                 }
                if(a[i][j][k]=='#')
                  {vis[i][j][k]=1;
                  }
                if(a[i][j][k]=='E')
                 {fx=i;fy=j;fz=k;
                 }
               }
              }
            }
            
        }

    地图是以字符的形式输入的,考虑到字符从下标0开始读入,这个题更加的恶心了....

    那就把整个地图的下标从0开始算吧。

    但是这个地图十分难画,因为像上面那样读入,第一个下标是层数(z轴),而不是x轴。既然如此,我们让z轴与x轴互换,对结果没有影响。

    接下来就是套迷宫题的模板

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int sx,sy,sz,fx,fy,fz,n,m,s;
    int dx[6]={1,-1,0,0,0,0},dy[6]={0,0,-1,1,0,0},dz[6]={0,0,0,0,1,-1};
    struct dl{
        int x,y,z,ds;
        dl(int xx,int yy,int zz,int ds):x(xx),y(yy),z(zz),ds(ds){}
    };
    bool vis[101][101][101];
    char a[101][101][101];
    bool hf(int xx,int yy,int zz)
    {if(xx<0||xx>=n||yy<0||yy>=m||zz<0||zz>=s)return 0;
     if(vis[xx][yy][zz])return 0;
     return 1;
    }
    void bfs()
    {queue<dl>q;
     vis[sx][sy][sz]=1;
      q.push(dl(sx,sy,sz,1));    
      /*for(int i=0;i<=n;i++)
          {for(int j=0;j<m;j++)
            for(int k=0;k<s;k++)
             {printf("vis[%d][%d][%d]=%d ",i,j,k,vis[i][j][k]);
             }
            printf("
    ");
          }*/
      while(!q.empty())
      {
          dl ex=q.front();
          q.pop();
      
          for(int i=0;i<6;i++)
          {int xx=ex.x,yy=ex.y,zz=ex.z;
          xx+=dx[i];yy+=dy[i];zz+=dz[i];
            if(hf(xx,yy,zz))
            {vis[xx][yy][zz]=1;
            //printf("xx=%d,yy=%d,zz=%d
    ",xx,yy,zz);
             int an=ex.ds+1;
             q.push(dl(xx,yy,zz,an));
          }
          if(xx==fx&&yy==fy&&zz==fz)
           {printf("Escaped in %d minute(s).
    ",ex.ds);return ;
             }  
        }
      }
      printf("Trapped!
    ");
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&s))
        {memset(vis,0,sizeof(vis));
         if(n==0&&m==0&&s==0)break;
           for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              scanf("%s",a[i][j]);
            }
            for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              {for(int k=0;k<s;k++)
               {if(a[i][j][k]=='S')
                 {sx=i;sy=j;sz=k;
                 }
                if(a[i][j][k]=='#')
                  {vis[i][j][k]=1;
                  }
                if(a[i][j][k]=='E')
                 {fx=i;fy=j;fz=k;
                 }
               }
              }
            }
            bfs();
        }
    }

     至于走出迷宫这个题,完全就是把三维迷宫减少了一个维度,再改一下输入,其余不变

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int sx,sy,sz,fx,fy,fz,n,m,s;
    int dx[4]={1,-1,0,0,},dy[4]={0,0,-1,1};
    struct dl{
        int x,y,ds;
        dl(int xx,int yy,int ds):x(xx),y(yy),ds(ds){}
    };
    bool vis[101][101];
    char a[101][101];
    bool hf(int xx,int yy)
    {if(xx<0||xx>=n||yy<0||yy>=m)return 0;
     if(vis[xx][yy])return 0;
     return 1;
    }
    void bfs()
    {queue<dl>q;
     vis[sx][sy]=1;
      q.push(dl(sx,sy,1));    
      /*for(int i=0;i<=n;i++)
          {for(int j=0;j<m;j++)
            for(int k=0;k<s;k++)
             {printf("vis[%d][%d][%d]=%d ",i,j,k,vis[i][j][k]);
             }
            printf("
    ");
          }*/
      while(!q.empty())
      {
          dl ex=q.front();
          q.pop();
      
          for(int i=0;i<4;i++)
          {int xx=ex.x,yy=ex.y;
          xx+=dx[i];yy+=dy[i];
            if(hf(xx,yy))
            {vis[xx][yy]=1;
            //printf("xx=%d,yy=%d,zz=%d
    ",xx,yy,zz);
             int an=ex.ds+1;
             q.push(dl(xx,yy,an));
          }
          if(xx==fx&&yy==fy)
           {printf("%d
    ",ex.ds);return ;
             }  
        }
      }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m);
        memset(vis,0,sizeof(vis));
           for(int i=0;i<n;i++)
            {
              scanf("%s",a[i]);
            }
            for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              {
               if(a[i][j]=='S')
                 {sx=i;sy=j;
                 }
                if(a[i][j]=='#')
                  {vis[i][j]=1;
                  }
                if(a[i][j]=='T')
                 {fx=i;fy=j;
                 }
              }
        }
        bfs();
    }

    走迷宫:把上个题的起点改为(0,0),终点改为(n-1,m-1),输出时+1即可

    输出时答案加一是因为我们输出的是出队ex.ds,而不是判断合法,加了1后入队的那个ex.ds,所以当前的出队点距离终点还差一步,所以要+1

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int sx,sy,sz,fx,fy,fz,n,m,s;
    int dx[4]={1,-1,0,0,},dy[4]={0,0,-1,1};
    struct dl{
        int x,y,ds;
        dl(int xx,int yy,int ds):x(xx),y(yy),ds(ds){}
    };
    bool vis[101][101];
    char a[101][101];
    bool hf(int xx,int yy)
    {if(xx<0||xx>=n||yy<0||yy>=m)return 0;
     if(vis[xx][yy])return 0;
     return 1;
    }
    void bfs()
    {queue<dl>q;
     vis[sx][sy]=1;
      q.push(dl(sx,sy,1));    
      /*for(int i=0;i<=n;i++)
          {for(int j=0;j<m;j++)
            for(int k=0;k<s;k++)
             {printf("vis[%d][%d][%d]=%d ",i,j,k,vis[i][j][k]);
             }
            printf("
    ");
          }*/
      while(!q.empty())
      {
          dl ex=q.front();
          q.pop();
          for(int i=0;i<4;i++)
          {int xx=ex.x,yy=ex.y;
          xx+=dx[i];yy+=dy[i];
            if(hf(xx,yy))
            {vis[xx][yy]=1;
            //printf("xx=%d,yy=%d,zz=%d
    ",xx,yy,zz);
             int an=ex.ds+1;
             q.push(dl(xx,yy,an));
          }
          if(xx==fx&&yy==fy)
           {printf("%d
    ",ex.ds+1);return ;
             }  
        }
      }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m);
        memset(vis,0,sizeof(vis));
        sx=0;sy=0;fx=n-1;fy=m-1;
           for(int i=0;i<n;i++)
            {
              scanf("%s",a[i]);
            }
            for(int i=0;i<n;i++)
            {for(int j=0;j<m;j++)
              {
                if(a[i][j]=='#')
                  {vis[i][j]=1;
                  }
              }
        }
        bfs();
    }
  • 相关阅读:
    RocketMQ源码 — 十、 RocketMQ顺序消息
    RocketMQ源码 — 九、 RocketMQ延时消息
    RocketMQ源码 — 八、 RocketMQ消息重试
    HDU3439 Sequence
    Cipolla算法学习小记
    BZOJ2286: [Sdoi2011]消耗战
    BZOJ4873 寿司餐厅
    BZOJ1718 [Usaco2006 Jan] Redundant Paths 分离的路径
    BZOJ1123 [POI2008]BLO
    BZOJ3996 TJOI2015线性代数
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/10744204.html
Copyright © 2020-2023  润新知