Nightmare Ⅱ
#include<bits/stdc++.h>
using namespace std;
#define maxn 888
char mmp[maxn][maxn];
bool vis1[maxn][maxn];
bool vis2[maxn][maxn];
int ans,n,m,t,cnt,step;
struct node
{
int x,y;
} boy,girl,ghost[5];
struct head
{
int x,y,f;
} top,temp;
bool judge(head te,int step)
{
for(int i=1; i<=2; i++)
if((abs(te.x-ghost[i].x)+abs(te.y-ghost[i].y))<=(step*2))
return false;
if(te.x<0||te.y<0||te.x>n-1||te.y>m-1||mmp[te.x][te.y]=='X'||mmp[te.x][te.y]=='Z')
return false;
if(te.f==1&&vis1[te.x][te.y]==1)
return false;
if(te.f==2&&vis2[te.x][te.y]==1)
return false;
return true;
}
int tog[5][5]= {{1,0},{0,1},{-1,0},{0,-1}};
int bfs()
{
step=0;
queue<head>qb,qg,qc,qd;
qb.push((head)
{
boy.x,boy.y,1
});
qg.push((head)
{
girl.x,girl.y,2
});
vis1[boy.x][boy.y]=1;
vis2[girl.x][girl.y]=1;
if(boy.x==girl.x&&boy.y==girl.y)
return 0;
while(!qb.empty()&&!qg.empty())
{
step++;
for(int j=0; j<3; j++)
{
qc=qb;
while(!qb.empty())
qb.pop();
while(!qc.empty())
{
top=qc.front();
qc.pop();
if(vis2[top.x][top.y]==1)
{
// cout<<" "<<top.x<<" "<<top.y<<endl;
return step;
}
for(int i=0; i<4; i++)
{
temp.x=top.x+tog[i][0];
temp.y=top.y+tog[i][1];
temp.f=top.f;
if(judge(temp,step))
{
qb.push(temp);
vis1[temp.x][temp.y]=1;
// cout<<step<<" "<<temp.x<<" "<<temp.y<<ghost[1].x<<" "<<ghost[1].y<<" "<<ghost[2].x<<" "<<ghost[2].y<<endl;
}
}
}
}
qd=qg;
while(!qg.empty())
qg.pop();
while(!qd.empty())
{
top=qd.front();
qd.pop();
if(vis1[top.x][top.y]==1)
{
// cout<<" "<<top.x<<" "<<top.y<<endl;
return step;
}
for(int i=0; i<4; i++)
{
temp.x=top.x+tog[i][0];
temp.y=top.y+tog[i][1];
temp.f=top.f;
if(judge(temp,step))
{
qg.push(temp);
vis2[temp.x][temp.y]=1;
}
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cnt=0;
cin>>n>>m;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
cin>>mmp[i][j];
if(mmp[i][j]=='Z')
{
ghost[++cnt].x=i;
ghost[cnt].y=j;
// cout<<cnt<<endl;
// cout<<i<<" "<<j<<endl;
}
else if(mmp[i][j]=='M')
{
boy.x=i;
boy.y=j;
}
else if(mmp[i][j]=='G')
{
girl.x=i;
girl.y=j;
}
vis1[i][j]=vis2[i][j]=0;
}
cout<<bfs()<<endl;
}
return 0;
}