poj2251 Dungeon Master

链接:http://poj.org/problem?id=2251

三维的搜索题,之前也没写过。用BFS。借鉴了网上的代码,写的不错,拿来用一下。这个题目的输入很有考验性,然后是三维的BFS的应用,都值得学习。

//又犯了一个低级错误,变量c1和c一开始重名了
#include<iostream>
#include<cstring>
using namespace std;

int maze[35][35][35];//三维的矩形空间
int vist[35][35][35];//记录是否被访问
int dis[35][35][35];//记录消耗的时间(走过的距离)
int q[30000];//队列,用数组实现
int l,r,c;

int dx[]={1,-1,0,0,0,0};//一共是6个方向
int dy[]={0,0,0,0,-1,1};
int dz[]={0,0,-1,1,0,0};

int BFS(int x,int y,int z)
{
	int front=0,rear=0,d,u;//头指针和尾指针都为0
	vist[x][y][z]=1;//起始点,被访问
	dis[x][y][z]=0;//初始走过的距离为0
	u=x*r*c+y*c+z;//这个方法我觉得很棒,以前从没见过
	q[rear++]=u;//起始点入队
	while(front<rear)
	{
	  u=q[front++];//队头出队
	  x=u/(r*c);
	  y=(u%(r*c))/c;
	  z=(u%(r*c))%c;//得到x、y、z
	  for(d=0;d<6;d++)//6个方向
	  {
		int nx=x+dx[d];
		int ny=y+dy[d];
		int nz=z+dz[d];
		if(nx>=0&&nx<l&&ny>=0&&ny<r&&nz>=0&&nz<c&&maze[nx][ny][nz]&&!vist[nx][ny][nz])
			            //如果没有越界且这个点可通行且未被访问,则入队
		{
		   int v=nx*r*c+ny*c+nz;
		   q[rear++]=v;   //入队
		   vist[nx][ny][nz]=1;  //标记,已访问
		   dis[nx][ny][nz]=dis[x][y][z]+1;  //距离加1
		   if(maze[nx][ny][nz]==2)      //到达E点
			   return dis[nx][ny][nz];
		}
	  }
	}
	return 0;  //不能到达,返回零
}
int main()
{
	int i,j,k;
	int a,b,c1,time;
	char s[40];
	
	while(cin>>l>>r>>c)
	{
	  if(!l&&!r&&!c)
		  return 0;
	  getchar();
	  memset(maze,0,sizeof(maze));
	  memset(vist,0,sizeof(vist));
	  for(i=0;i<l;i++)
	  {
		  for(j=0;j<r;j++)
		  {
		      gets(s);
			  for(k=0;k<c;k++)
			  {
			    if(s[k]=='S')
				{
				  a=i;
				  b=j;
				  c1=k;
				}
				else if(s[k]=='.')
					maze[i][j][k]=1;
				else if(s[k]=='E')
					maze[i][j][k]=2;
			  }
		  }
		  getchar();
	  }
	  time=BFS(a,b,c1);
	  if(time)
		  cout<<"Escaped in "<<time<<" minute(s)."<<endl;
	  else
		  cout<<"Trapped!"<<endl;
	}
  return 0;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值