一本通之 一堆迷宫 (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("\n");
      }*/
  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\n",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).\n",ex.ds);return ;
         }  
    }
  }
  printf("Trapped!\n");
}
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("\n");
      }*/
  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\n",xx,yy,zz);
         int an=ex.ds+1;
         q.push(dl(xx,yy,an));
      }
      if(xx==fx&&yy==fy)
       {printf("%d\n",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("\n");
      }*/
  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\n",xx,yy,zz);
         int an=ex.ds+1;
         q.push(dl(xx,yy,an));
      }
      if(xx==fx&&yy==fy)
       {printf("%d\n",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();
}

 

posted @ 2019-04-21 10:59  千载煜  阅读(406)  评论(0编辑  收藏  举报