由于可以回到原地,所以多种状态可以叠加,不处理容易超时。增加一个二维数组判断到该点时剩余时间的最大值,如果当前状态的剩余时间大于该值,则加入队列,否则舍弃。
#include <cstdio> #include <cstring> #include <queue> #include <iostream> using namespace std; const int maxn =10+5; int a[maxn][maxn]; int n,m,si,sj; bool hash[maxn][maxn]; int mi[maxn][maxn]; int dir[4][2]= {{1,0},{0,1},{-1,0},{0,-1}}; struct node { int x,y,t,s; }; int BFS() { queue<node>q; node cur,next; cur.x=si,cur.y=sj;cur.t=0,cur.s=0; memset(hash,0,sizeof(hash)); hash[cur.x][cur.y]=1; q.push(cur); while(!q.empty()) { cur=q.front(); q.pop(); for(int i=0; i<4; i++) { next=cur; next.x+=dir[i][0]; next.y+=dir[i][1]; next.t++; next.s++; if(next.t>=6) continue; if(next.x<0||next.x>=n||next.y<0||next.y>=m) continue; if(a[next.x][next.y]==0) continue; if(a[next.x][next.y]==3) return next.s; if(a[next.x][next.y]==4) next.t=0; if(!hash[next.x][next.y]) { hash[next.x][next.y]=1; q.push(next); } else if(mi[next.x][next.y]<6-next.t) { q.push(next); mi[next.x][next.y]=6-next.t; } } } return -1; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) for(int j=0; j<m; j++) { scanf("%d",&a[i][j]); if(a[i][j]==2) si=i,sj=j; } memset(mi,0,sizeof(mi)); printf("%d\n",BFS()); } return 0; }