/* 有两种做法: 一个不考虑走了回头路,因为数据是在是小,几乎不浪费时间 另一个是用贪心策略,先假设所有点剩余时间为0,只要该点剩余时间小于 上一点剩余时间-1 则修改remain值为remain-1再入队,否则不入队 */ #include <iostream> #include <cstring> #include <cstdio> #include <queue> #include <algorithm> using namespace std; #define CLR(c,v) (memset(c,v,sizeof(c))) const int M = 30; const int wall = 0; const int road = 1; const int start = 2; const int end = 3; const int reset = 4; const int bomblimit = 6; int revise[][2] = {{-1,0}, {0,-1},{0,1}, {1,0}}; int map[M][M]; int limit[M][M]; int n,m; // n*m struct _P{ int x,y; int step,remain; _P(int x=-1,int y=-1,int step=0,int remain=0):x(x),y(y),step(step),remain(remain){} bool operator <(const _P& p){ return step > p.step; } bool operator ==(const _P& p){ return (x==p.x) && (y==p.y); } }S,E; typedef _P NEXT; typedef _P NOW; int BFS(){ queue<_P> que; que.push(S); while(!que.empty()){ NOW now = que.front(); que.pop(); if (now == E){ return now.step; } for (int i = 0 ; i < 4 ; i++){ int nx = now.x + revise[i][0]; int ny = now.y + revise[i][1]; int re = now.remain - 1; if ( !(nx >= 0 && nx < n && ny >= 0 && ny < m ) || re <= 0)continue; // 出界 或 时间耗尽 if (map[nx][ny] == wall)continue; NEXT next = NEXT( nx, ny, now.step+1, re ); if (map[nx][ny] == reset){ next.remain = bomblimit; } if (limit[nx][ny] < next.remain){ // 只有当剩余时间发现-1之后 还长的 才入队 limit[nx][ny] = next.remain; que.push(next); } } } return -1; } int main(){ //freopen("in.txt","r",stdin); //freopen("Input.txt","r",stdin); //freopen("out.txt","w",stdout); int Ncase,g; cin >> Ncase; while(Ncase -- ){ cin >> n >> m; CLR(limit,0); for (int i = 0 ; i <n ; i ++){ for (int j = 0 ; j < m ; j++){ scanf("%d",&g); map[i][j] = g; //limit[i][j] = 0; // 初始化 if (g == start){ S = _P(i,j,0,bomblimit); limit[i][j] = bomblimit; }else if(g == end){ E = _P(i,j,0,0); map[i][j] = road; } } } cout << BFS() << endl; } return 0; } /* 一些变态的数据,不符合input 13 8 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 1 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 4 4 2 1 1 1 1 1 1 1 1 1 4 1 1 1 1 3 20 20 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 5 8 1 2 1 1 1 1 1 4 1 0 0 0 1 0 0 1 1 4 1 0 1 1 0 1 1 0 0 0 0 3 0 1 1 1 4 1 1 1 1 1 2 8 2 1 1 1 1 1 1 0 0 0 1 4 1 1 1 3 8 8 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2 1 2 3 3 3 2 1 1 1 1 0 1 1 3 4 8 2 1 1 0 1 1 1 0 1 0 4 1 1 0 4 1 1 0 0 0 0 0 0 1 1 1 1 4 1 1 1 3 1 2 2 3 3 3 2 4 1 1 4 1 1 4 3 1 8 2 4 4 4 4 4 4 3 1 8 2 0 0 0 0 0 0 3 8 8 2 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 4 1 0 0 0 0 0 0 1 3 8 8 2 1 4 4 0 0 0 0 1 0 1 0 0 0 0 0 0 1 4 1 0 4 0 0 4 0 1 0 1 0 0 0 0 0 1 1 4 1 1 4 0 0 4 0 1 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 4 0 1 3 */