题目86:胜利大逃亡

来源:互联网 发布:数据建模的方法 编辑:程序博客网 时间:2024/05/22 09:51
//http://ac.jobdu.com/problem.php?cid=1040&pid=85
#include <stdio.h>#include <queue>using namespace std;struct N             //状态结构体{int x,y,z;       //位置坐标int t;           //所需时间};bool mark[51][51][51]; //标记数组,扩展出(x,y,z)之后记为true,再次扩展出来后直接丢弃int maze[51][51][51];  //保存立方体信息  queue<N> Q;            //队列中元素是状态(x,y,z,t)    int go[][3]=          //坐标变换数组,(x,y,z)->(x+go[i][0],y+go[i][1],z+go[i][2]){1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1,};int BFS(int a,int b,int c)  //广度优先搜索,返回到达目的点的最少耗时{  while (Q.empty()==false)  //当仍有元素可以扩展时循环  {    N now=Q.front();Q.pop();for (int i=0;i<6;i++)   //依次扩展6个相邻节点{      int nx=now.x+go[i][0];  int ny=now.y+go[i][1];  int nz=now.z+go[i][2];    if (nx<0 || nx>=a || ny<0 || ny>=b || nz<0 || nz>=c )  {  continue;         //若新坐标再正方体外,丢弃该坐标  }  if (maze[nx][ny][nz]==1)  {  continue;         //若新坐标为墙,丢弃    }  if (mark[nx][ny][nz]==true)  {  continue;         //若该状态已经得到过,则丢弃,因为时间必定大于上次  }        N tmp;               //新状态  tmp.x=nx;  tmp.y=ny;  tmp.z=nz;  tmp.t=now.t+1;  Q.push(tmp);         //该状态放入队列,因为广度优先按照被查找到的顺序依次扩展下一层  mark[nx][ny][nz]=true; //标记该坐标  if (nx==a-1 && ny==b-1 && nz==c-1)  {  return tmp.t;        //若是终点,返回其耗时  }}  }  return -1;              //所有状态都被查找完,仍得不到所需坐标,返回-1}int main(){int T,i,j,k;scanf("%d",&T);while (T--){int a,b,c,t;scanf("%d%d%d%d",&a,&b,&c,&t);for(i=0;i<a;i++)                   //初始化{for (j=0;j<b;j++){               for (k=0;k<c;k++)   {   scanf("%d",&maze[i][j][k]);//输入立方体信息   mark[i][j][k]=false;       //初始化标记数组     }}}while (Q.empty()==false){Q.pop();                       //清空队列,防止上组数据遗留                 }        mark[0][0][0]=true;          //标记起点N tmp;tmp.t=tmp.x=tmp.y=tmp.z=0;   //初始状态Q.push(tmp);                 int rec=BFS(a,b,c);          //广度优先搜索if (rec<=t){printf("%d\n",rec);}else{printf("-1\n");}}return 0;}


原创粉丝点击