简要题意及解析
1001
第三次作业原题,略。
1002
把一个数转换为二进制。
不断除以(2)取余就好了。写递归代码会非常短。
时间复杂度(O(Tlogn))
(T)是数据组数,(n)如题意。
1003
第二次作业原题,略。
1004
有三个容量分别为(S,N,M)的容器,初始状态(S)装满可乐,(N,M)为空。三个容器之间可以互相倒可乐,不过三个容器都没有刻度,也就是说若(a)向(b)中倒可乐,必须把(a)倒空或者把(b)倒满。求最少倒几次才能把(S)中的可乐平分。平分的定义是:三个容器其中一个为空,另外两个所装可乐相等。不能中途把可乐喝掉。。。
当前局面的状态可以用三个容器中的可乐量,也就是一个三元组((a,b,c))表示。我们从初状态((S,0,0))开始(bfs),第一次到达平分状态所需步数就是答案。注意之前搜索到的状态不需要再次搜索,要开一个标记数组。
因此最差情况为每个状态都搜索一次。
时间复杂度(O(TSNM))。
(T)为数据组数,(S,N,M)如题意。
1005
迷宫问题变形。这个迷宫有两层,你在某些位置会切换当前所在层。
做法和普通迷宫区别不大,用三元组——当前层数、(x)坐标和(y)坐标表示当前位置即可。
题目有一些坑,到达(#)时必须切换所在层,要判断切换后直接到达终点,如果切换后碰到墙会撞死、切换后碰到(#)会死循环。所以如果切换后碰到(*)或(#)一定不能去这个切换点。
时间复杂度(O(Tnm))
(T)为数据组数,(n,m)如题意。
1006
迷宫问题变形。迷宫变成了三维。
坐标变成三维,方向变成(6)种,其他照旧(bfs)。
时间复杂度(O(TABC))
(T)为数据组数,(A,B,C)如题意。
1007
最大团问题。
给出一个图,找一个它的子图使得这个子图是完全图,求这个子图最多有几个点。
暴力搜索每个点要还是不要,需要优化剪枝。
在加入点的时候需要判断加入后是否是完全图,不是的话就不用加了——可行性剪枝。如果当前点数加未搜索点数不能超过最优方案,不用继续搜索了——最优化剪枝。
另外,可以把每个点的连边情况用二进制数表示,压在一个(long~~long)里面,这样做的好处是可以快速判断加入一个点后是否是完全图。
时间复杂度(O(T2^n)),实际复杂度远低于上界。
(T)为数据组数,(n)为点数。
1008
地图上有最多(100)个数量相等的(m)和(H),要把所有(m)分别送到不同的(H)处,代价是两个点的曼哈顿距离。求最小代价。
暴力枚举每个(m)要去哪个(H),感觉会超时。或许有一些特殊的姿势可以通过。
其实这是一个二分图最小权匹配问题。从每个(m)向(H)连边,边权为曼哈顿距离。最小权匹配即为答案。
我用费用流做了。
时间复杂度(O(Tk^5))
(T)为数据组数,(k)为(m)的数量。
1009
给出(n)个仅含(A,G,C,T)的串,构造一个仅含(A,G,C,T)的串使得这(n)个串都是它的子序列。求构造串最小长度。
求最小步数用(bfs),当前状态用(n)个数——构造串覆盖了这(n)个串的前几个表示。(bfs)的时候通过枚举构造串的下一个字符是什么来进行转移。注意搜索过得状态不用再搜索。
时间复杂度(O(TL^n))
(T)为数据组数,(n)如题意,(L)为每个串的长度。
1010
在一个(M*N)的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子。求最少步数。
最小步数用(bfs),当前状态用搬运工和箱子的坐标这个四元组表示。搬运工可以向四周移动,如果搬运工与箱子重合,视为搬运工推动了一次箱子。模拟进行状态转移即可。搜索过的状态不用再搜索。
时间复杂度(O(TN^2M^2))
(T)为数据组数,(N,N)如题意。
代码警告
代码警告
代码警告
代码警告
代码警告
代码警告
代码合集:
//1001
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=105,ws_[4]={0,1,0,-1},ad_[4]={1,0,-1,0};
int N,M;
char mp[maxn][maxn];
struct status{
int x,y,t;
status(int x=0,int y=0,int t=0){
this->x=x,this->y=y,this->t=t;
}
bool friend operator<(const status&A,const status&B){
return A.t>B.t;
}
}from[maxn][maxn];
priority_queue<status>pq;
int vis[maxn][maxn];
inline bool out(int x,int y){
return x<=0||y<=0||x>N||y>M;
}
void bfs(){
memset(vis,10,sizeof(vis));
pq.push(status(1,1,0));
vis[1][1]=0;
while(!pq.empty()){
status s=pq.top();
pq.pop();
for(int i=0;i<4;i++){
int tx=s.x+ws_[i],ty=s.y+ad_[i],tt=s.t+1;
if(out(tx,ty)||mp[tx][ty]=='X')
continue;
if(mp[tx][ty]>='1'&&mp[tx][ty]<='9')
tt+=mp[tx][ty]-'0';
if(tt<vis[tx][ty]){
vis[tx][ty]=tt;
pq.push(status(tx,ty,tt));
from[tx][ty]=s;
}
}
}
}
void dfs(int x,int y){
if(x==1&&y==1)
return;
status pre=from[x][y];
dfs(pre.x,pre.y);
printf("%ds:(%d,%d)->(%d,%d)
",pre.t+1,pre.x-1,pre.y-1,x-1,y-1);
if(mp[x][y]>='1'&&mp[x][y]<='9')
for(int i=1;i<=mp[x][y]-'0';i++)
printf("%ds:FIGHT AT (%d,%d)
",pre.t+i+1,x-1,y-1);
}
int main(){
//freopen("in","r",stdin);
while(scanf("%d%d",&N,&M)!=EOF){
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
mp[i][j]=one();
bfs();
if(vis[N][M]==vis[0][0])
puts("God please help our poor hero.");
else{
printf("It takes %d seconds to reach the target position, let me show you the way.
",vis[N][M]);
dfs(N,M);
}
puts("FINISH");
}
return 0;
}
//1002
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
void trans(int x){
if(!x)return;
trans(x/2);
printf("%d",x%2);
}
int main(){
//freopen("in","r",stdin);
int n;
while(scanf("%d",&n)!=EOF){
trans(n);
puts("");
}
return 0;
}
//1003
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=10010;
int N,M,w[maxn];
double v[maxn];
double f[maxn];
int main(){
//freopen("in","r",stdin);
while(1){
N=read(),M=read();
if(N+M==0)break;
for(int i=0;i<=N;i++)
f[i]=-1;
for(int i=1;i<=M;i++)
w[i]=read(),scanf("%lf",&v[i]);
f[0]=0;
for(int i=1;i<=M;i++)
for(int j=N;j>=w[i];j--)
if(f[j-w[i]]>=0)
f[j]=max(f[j],f[j-w[i]]+(1-f[j-w[i]])*v[i]);
double ans=0;
for(int i=0;i<=N;i++)
ans=max(ans,f[i]);
printf("%.1lf%%
",ans*100);
}
return 0;
}
//1004
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
struct my{
int x,y,s;
my(int xx=0,int yy=0,int ss=0){
x=xx,y=yy,s=ss;
}
};
queue<my>q;
bool vis[110][110];
bool check(int x,int y,int z){
if(!x)return y==z;
else if(!y)return x==z;
else if(!z)return x==y;
return 0;
}
int bfs(int a,int b,int c){
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
q.push(my(0,0,0));
vis[0][0]=1;
while(!q.empty()){
my tmp=q.front();
q.pop();
int rem=a-tmp.x-tmp.y;
if(check(tmp.x,tmp.y,rem))
return tmp.s;
int t=min(b-tmp.x,rem);
if(!vis[tmp.x+t][tmp.y]){
vis[tmp.x+t][tmp.y]=1;
q.push(my(tmp.x+t,tmp.y,tmp.s+1));
}//a to b
if(!vis[0][tmp.y]){
vis[0][tmp.y]=1;
q.push(my(0,tmp.y,tmp.s+1));
}//b to a
t=min(c-tmp.y,rem);
if(!vis[tmp.x][tmp.y+t]){
vis[tmp.x][tmp.y+t]=1;
q.push(my(tmp.x,tmp.y+t,tmp.s+1));
}//a to c
if(!vis[tmp.x][0]){
vis[tmp.x][0]=1;
q.push(my(tmp.x,0,tmp.s+1));
}//c to a
t=min(tmp.x,c-tmp.y);
if(!vis[tmp.x-t][tmp.y+t]){
vis[tmp.x-t][tmp.y+t]=1;
q.push(my(tmp.x-t,tmp.y+t,tmp.s+1));
}//b to c
t=min(b-tmp.x,tmp.y);
if(!vis[tmp.x+t][tmp.y-t]){
vis[tmp.x+t][tmp.y-t]=1;
q.push(my(tmp.x+t,tmp.y-t,tmp.s+1));
}//c to b
}
return -1;
}
int main(){
//freopen("in","r",stdin);
while(1){
int a=read(),b=read(),c=read();
if(a+b+c==0)break;
int res=bfs(a,b,c);
if(res==-1)puts("NO");
else printf("%d
",res);
}
return 0;
}
//1005
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=12;
const int ws_[4]={1,0,-1,0},ad_[4]={0,1,0,-1};
int N,M,T;
char mp[2][maxn][maxn];
struct pos{
int z,x,y,v;
pos(int zz=0,int xx=0,int yy=0,int vv=0){
z=zz,x=xx,y=yy,v=vv;
}
};
queue<pos>q;
bool vis[2][maxn][maxn];
inline bool out(int x,int y){
return x<1||y<1||x>N||y>M;
}
bool bfs(){
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
q.push(pos(0,1,1,0));
vis[0][1][1]=1;
while(!q.empty()){
pos p=q.front();
q.pop();
if(mp[p.z][p.x][p.y]=='P')
return p.v<=T;
if(p.v>T)break;
for(int i=0;i<4;i++){
int tx=p.x+ws_[i],ty=p.y+ad_[i];
if(out(tx,ty))continue;
if(mp[p.z][tx][ty]=='*')continue;
if(mp[p.z][tx][ty]=='#'){
if(!vis[!p.z][tx][ty]&&mp[!p.z][tx][ty]!='*'&&mp[!p.z][tx][ty]!='#'){
vis[!p.z][tx][ty]=1;
q.push(pos(!p.z,tx,ty,p.v+1));
}
continue;
}
if(!vis[p.z][tx][ty]){
vis[p.z][tx][ty]=1;
q.push(pos(p.z,tx,ty,p.v+1));
}
}
}
return 0;
}
int main(){
//freopen("in","r",stdin);
for(int _=read();_;_--){
N=read(),M=read(),T=read();
for(int k=0;k<=1;k++)
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
mp[k][i][j]=one();
if(bfs())puts("YES");
else puts("NO");
}
return 0;
}
//1006
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=52;
const int ws_[6]={1,-1,0,0,0,0},ad_[6]={0,0,1,-1,0,0},qe_[6]={0,0,0,0,1,-1};
int N,M,K,T;
int mp[maxn][maxn][maxn];
struct pos{
int x,y,z,v;
pos(int xx=0,int yy=0,int zz=0,int vv=0){
x=xx,y=yy,z=zz,v=vv;
}
};
queue<pos>q;
bool vis[maxn][maxn][maxn];
inline bool out(int x,int y,int z){
return x<1||y<1||z<1||x>K||y>N||z>M;
}
int bfs(){
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
q.push(pos(1,1,1,0));
while(!q.empty()){
pos p=q.front();
q.pop();
for(int i=0;i<6;i++){
int tx=p.x+ws_[i],ty=p.y+ad_[i],tz=p.z+qe_[i];
if(out(tx,ty,tz))continue;
if(mp[tx][ty][tz])continue;
if(vis[tx][ty][tz])continue;
if(tx==K&&ty==N&&tz==M){
if(p.v+1<=T)return p.v+1;
else return -1;
}
vis[tx][ty][tz]=1;
q.push(pos(tx,ty,tz,p.v+1));
}
}
return -1;
}
int main(){
//freopen("in","r",stdin);
for(int _=read();_;_--){
K=read(),N=read(),M=read(),T=read();
for(int k=1;k<=K;k++)
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
mp[k][i][j]=read();
printf("%d
",bfs());
}
return 0;
}
//1007
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=52;
int N,ans,a[maxn],cnt,deg[maxn];
bool e[maxn][maxn];
long long lin[maxn];
inline bool check(int x,long long s){
return (lin[x]&s)==s;
}
void dfs(int x,long long s){
if(x==N+1)
return;
if(cnt+N-x+1<=ans)
return;
if(deg[x]>=ans)
if(check(x,s)){
a[++cnt]=x;
ans=max(ans,cnt);
dfs(x+1,s|(1LL<<x));
cnt--;
}
dfs(x+1,s);
}
int main(){
//freopen("in","r",stdin);
while(1){
N=read();
if(!N)break;
for(int i=1;i<=N;i++){
lin[i]=deg[i]=0;
for(int j=1;j<=N;j++){
e[i][j]=read();
if(e[i][j]){
deg[i]++;
lin[i]|=(1LL<<j);
}
}
}
ans=0;
dfs(1,0);
printf("%d
",ans);
}
return 0;
}
//1008
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=110,INF=1<<30;
int N,M,ans,A,B;
char mp[maxn][maxn];
pair<int,int>a[maxn],b[maxn];
int lin[maxn*2],len;
struct edge{
int y,next,flow,v;
}e[maxn*maxn*2];
inline void insert(int xx,int yy,int ff,int vv){
e[++len].next=lin[xx];
lin[xx]=len;
e[len].y=yy;
e[len].flow=ff;
e[len].v=vv;
}
inline void ins(int xx,int yy,int ff,int vv){
insert(xx,yy,ff,vv);
insert(yy,xx,0,-vv);
//printf("%d %d %d %d
",xx,yy,ff,vv);
}
int dis[maxn*2],pre[maxn*2],useedge[maxn*2],q[maxn*maxn],head,tail,ss,ee;
bool vis[maxn*2];
bool SPFA(){
memset(vis,0,sizeof(vis));
memset(dis,10,sizeof(dis));
head=tail=0;
q[head]=ss,vis[ss]=1,dis[ss]=0;
for(;head<=tail;head++){
vis[q[head]]=0;
for(int i=lin[q[head]];i;i=e[i].next){
if(e[i].flow&&(dis[e[i].y]>dis[q[head]]+e[i].v)){
dis[e[i].y]=dis[q[head]]+e[i].v;
if(!vis[e[i].y]){
vis[e[i].y]=1;
q[++tail]=e[i].y;
}
pre[e[i].y]=q[head];
useedge[e[i].y]=i;
}
}
}
return dis[ee]!=dis[0];
}
void agu(){
int add=INF;
for(int i=ee;i!=ss;i=pre[i])
add=min(add,e[useedge[i]].flow);
for(int i=ee;i!=ss;i=pre[i]){
e[useedge[i]].flow-=add;
if(useedge[i]&1)
e[useedge[i]+1].flow+=add;
else
e[useedge[i]-1].flow+=add;
ans+=add*e[useedge[i]].v;
}
}
void cost_flow(){
ans=0;
while(SPFA())
agu();
}
int calc(int x,int y){
return abs(a[x].first-b[y].first)+abs(a[x].second-b[y].second);
}
void build(){
memset(lin,0,sizeof(lin));len=0;
ss=A+B+1,ee=A+B+2;
for(int i=1;i<=A;i++)
ins(ss,i,1,0);
for(int i=1;i<=B;i++)
ins(i+A,ee,1,0);
for(int i=1;i<=A;i++)
for(int j=1;j<=B;j++)
ins(i,j+A,1,calc(i,j));
}
int main(){
//freopen("in","r",stdin);
while(1){
N=read(),M=read();A=B=0;
if(N+M==0)break;
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++){
mp[i][j]=one();
if(mp[i][j]=='m')
a[++A]=make_pair(i,j);
else if(mp[i][j]=='H')
b[++B]=make_pair(i,j);
}
build();
cost_flow();
printf("%d
",ans);
}
return 0;
}
//1009
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=8,ws_[4]={1,-1,0,0},ad_[4]={0,0,1,-1};
int N,M,mp[maxn][maxn],ax,ay,bx,by;
struct status{
int sx,sy,fx,fy,v;
status(int sx=0,int sy=0,int fx=0,int fy=0,int v=0){
this->sx=sx,this->sy=sy,this->fx=fx,this->fy=fy,this->v=v;
}
bool friend operator<(const status&A,const status&B){
if(A.sx!=B.sx)return A.sx<B.sx;
if(A.sy!=B.sy)return A.sy<B.sy;
if(A.fx!=B.fx)return A.fx<B.fx;
return A.fy<B.fy;
}
};
deque<status>q;
map<status,bool>vis;
inline bool out(int x,int y){
return x<1||y<1||x>N||y>M;
}
int bfs(){
vis.clear();
while(!q.empty())q.pop_front();
status init(ax,ay,bx,by);
vis[init]=1;
q.push_front(init);
while(!q.empty()){
status t=q.front();
q.pop_front();
for(int i=0;i<4;i++){
status nxt=t;
nxt.fx=t.fx+ws_[i],nxt.fy=t.fy+ad_[i];
if(out(nxt.fx,nxt.fy))continue;
if(mp[nxt.fx][nxt.fy]==1)continue;
if(nxt.fx==nxt.sx&&nxt.fy==nxt.sy){
nxt.sx+=ws_[i],nxt.sy+=ad_[i];
if(out(nxt.sx,nxt.sy))continue;
if(mp[nxt.sx][nxt.sy]==1)continue;
if(!vis[nxt]){
nxt.v++;
if(mp[nxt.sx][nxt.sy]==3)
return nxt.v;
vis[nxt]=1;
q.push_back(nxt);
}
}
else{
if(!vis[nxt]){
vis[nxt]=1;
q.push_front(nxt);
}
}
}
}
return -1;
}
int main(){
//freopen("in","r",stdin);
for(int _=read();_;_--){
N=read(),M=read();
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++){
mp[i][j]=read();
if(mp[i][j]==2)ax=i,ay=j;
else if(mp[i][j]==4)bx=i,by=j;
}
printf("%d
",bfs());
}
return 0;
}
//1010
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<utility>
#include<iomanip>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
long long READ(){
long long xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
return xx*ff;
}
char one(){
char ch=getchar();
while(ch==' '||ch=='
')
ch=getchar();
return ch;
}
const int maxn=8,ws_[4]={1,-1,0,0},ad_[4]={0,0,1,-1};
int N,M,mp[maxn][maxn],ax,ay,bx,by;
struct status{
int sx,sy,fx,fy,v;
status(int sx=0,int sy=0,int fx=0,int fy=0,int v=0){
this->sx=sx,this->sy=sy,this->fx=fx,this->fy=fy,this->v=v;
}
bool friend operator<(const status&A,const status&B){
if(A.sx!=B.sx)return A.sx<B.sx;
if(A.sy!=B.sy)return A.sy<B.sy;
if(A.fx!=B.fx)return A.fx<B.fx;
return A.fy<B.fy;
}
};
deque<status>q;
map<status,bool>vis;
inline bool out(int x,int y){
return x<1||y<1||x>N||y>M;
}
int bfs(){
vis.clear();
while(!q.empty())q.pop_front();
status init(ax,ay,bx,by);
vis[init]=1;
q.push_front(init);
while(!q.empty()){
status t=q.front();
q.pop_front();
for(int i=0;i<4;i++){
status nxt=t;
nxt.fx=t.fx+ws_[i],nxt.fy=t.fy+ad_[i];
if(out(nxt.fx,nxt.fy))continue;
if(mp[nxt.fx][nxt.fy]==1)continue;
if(nxt.fx==nxt.sx&&nxt.fy==nxt.sy){
nxt.sx+=ws_[i],nxt.sy+=ad_[i];
if(out(nxt.sx,nxt.sy))continue;
if(mp[nxt.sx][nxt.sy]==1)continue;
if(!vis[nxt]){
nxt.v++;
if(mp[nxt.sx][nxt.sy]==3)
return nxt.v;
vis[nxt]=1;
q.push_back(nxt);
}
}
else{
if(!vis[nxt]){
vis[nxt]=1;
q.push_front(nxt);
}
}
}
}
return -1;
}
int main(){
//freopen("in","r",stdin);
for(int _=read();_;_--){
N=read(),M=read();
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++){
mp[i][j]=read();
if(mp[i][j]==2)ax=i,ay=j;
else if(mp[i][j]==4)bx=i,by=j;
}
printf("%d
",bfs());
}
return 0;
}