这道题是一道bfs的题目,因为题目中给的数据很小,所以可以采用优先队列的方式来简化处理。这道题在搜索的过程中要注意map1的不同层次的转换,即对‘#‘的理解。之前wa了两次是因为我考虑了如果上下两层对应位置都是‘#‘时输出‘NO’,但是这是错误的,可以不考虑这个问题,也可以当上下两层都是‘#’时将它们赋成‘*’;
具体步骤看程序及程序上的注释:
#include"iostream" #include"stdio.h" #include"cmath" #include"string.h" #include"queue" #include"algorithm" #define mx 15 using namespace std; char map1[mx][mx][2];//三维的地图 int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};//上下左右四个方向 int n,m,t,sx,sy,sz,ex,ey,ez; struct node { int x,y,z,time; friend bool operator<(node a,node b)//优先队列中的元素按时间的从小到大排序 { return b.time<a.time; } }; int judge(int x,int y,int z)//判断当前位置的情况 { if(x>=0&&x<n&&y>=0&&y<m) { if(map1[x][y][z]==‘.‘) return 0; else if(map1[x][y][z]==‘#‘) return 1; else return -1; } else return -1; } void bfs() { priority_queue<node> q;//构造优先队列 node cur,next; int i; cur.x=sx; cur.y=sy; cur.z=sz; cur.time=0; q.push(cur); while(!q.empty())//队列非空就进行循环 { cur=q.top(); q.pop();//记得出队列 if(cur.x==ex&&cur.y==ey&&cur.z==ez&&cur.time<=t)//找到了目标位置就输出并返回 {cout<<"YES"<<endl;return;} for(i=0;i<4;i++) { next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; next.z=cur.z; int re=judge(next.x,next.y,next.z);//判断走过一步后的情况 if(re==-1) continue; else { if(re==0) { map1[next.x][next.y][next.z]=‘*‘; next.time=cur.time+1; q.push(next); } else if(re==1) { next.z=(cur.z+1)%2; re=judge(next.x,next.y,next.z);//判断时空隧道的对应位置是什么 if(re==0) { next.time=cur.time+1;map1[next.x][next.y][next.z]=‘*‘;q.push(next);} } } } } cout<<"NO"<<endl; } int main() { int c; cin>>c; while(c--) { int i,j,k; cin>>n>>m>>t; for(k=0;k<=1;k++) { for(i=0;i<n;i++) { for(j=0;j<m;j++) { cin>>map1[i][j][k]; if(map1[i][j][k]==‘S‘) { sx=i;sy=j;sz=k; map1[i][j][k]=‘*‘; } else if(map1[i][j][k]==‘P‘) { map1[i][j][k]=‘.‘; ex=i;ey=j;ez=k; } } } if(k==0)getchar();////注意在输入过程中的空格 } bfs(); } return 0; }
时间: 2024-10-07 05:16:40