解题思路
鬼的覆盖范围不需要特别处理,只需要O(1)判断一下走没走到鬼的覆盖范围
接下来就是boy & girl了,
每秒boy走三步,girl走一步就很迷: )
他俩必须同时BFS,但是是两个不同的队列
那么boy直接就加一层循环寻三步就ok了
boy & girl走到的点分别开数组标记,当两个数组在每个位置上都被标记了,就代表他们会和了,输出当时用的时间。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
const int dx[5]= {
0,1,0,-1,0};
const int dy[5]= {
0,0,-1,0,1};
bool ok=0;
int T,n,m,a[810][810],kj[3][3],f1[1000000][3],f2[1000000][3],v1[810][810],v2[810][810];
char c;
bool check1(int x,int y,int s) {
if(x>0&&y>0&&x<=n&&y<=m&&a[x][y]!=1&&a[x][y]!=-1) {
int lyx1=abs(kj[1][1]-x)+abs(kj[1][2]-y),lyx2=abs(kj[2][1]-x)+abs(kj[2][2]-y);
if(lyx1>s*2&&lyx2>s*2)
return 1;
else
return 0;
} else return 0;
}
bool check2(int x,int y,int s) {
if(x>0&&y>0&&x<=n&&y<=m&&a[x][y]!=1&&a[x][y]!=-1) {
int lyx1=abs(kj[1][1]-x)+abs(kj[1][2]-y),lyx2=abs(kj[2][1]-x)+abs(kj[2][2]-y);
if(lyx1>s*2&&lyx2>s*2)
return 1;
else
return 0;
} else return 0;
}
inline int read()
{
int x=0,f=1;
char s=getchar();
while(s<'0'||s>'9')
{
if(s=='-') f=-f;
s=getchar();
}
while(s>='0'&&s<='9')
x=x*10+s-'0',s=getchar();
return x*f;
}
void bfs() {
int h1=0,t1=1,h2=0,t2=1,s1=0,e1=1,s2=0,e2=1;
for(int s=1; h1!=t1||h2!=t2; s++) {
for(int i=1; i<=3; i++) {
for(int j=abs(s1-e1); j>0; j--) {
h1=(h1%999999)+1,s1++;
for(int ii=1; ii<=4; ii++) {
int xx=f1[h1][1]+dx[ii],yy=f1[h1][2]+dy[ii];
if(check1(xx,yy,s)&&!v1[xx][yy]&&check1(f1[h1][1],f1[h1][2],s)) {
t1=(t1%999999)+1,e1++;
f1[t1][1]=xx,f1[t1][2]=yy;
v1[xx][yy]=1;
if(v2[xx][yy]==1) {
printf("%d\n",s);
return ;
}
}
}
}
}
for(int j=abs(s2-e2); j>0; j--) {
h2=(h2%999999)+1,s2++;
for(int ii=1; ii<=4; ii++) {
int xx=f2[h2][1]+dx[ii],yy=f2[h2][2]+dy[ii];
if(check2(xx,yy,s)&&!v2[xx][yy]&&check2(f2[h2][1],f2[h2][2],s)) {
t2=(t2%999999)+1,e2++;
f2[t2][1]=xx,f2[t2][2]=yy;
v2[xx][yy]=1;
if(v1[xx][yy]==1) {
printf("%d\n",s);
return ;
}
}
}
}
}
cout<<-1<<endl;
return;
}
int main() {
T=read();
while(T--) {
memset(v1,0,sizeof(v1));
memset(v2,0,sizeof(v2));
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
ok=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cin>>c;
if(c=='X') a[i][j]=1;
if(c=='Z'&&!ok)
kj[1][1]=i,kj[1][2]=j,a[i][j]=-1,ok=1;
if(c=='Z'&&ok==1)
kj[2][1]=i,kj[2][2]=j,a[i][j]=-1;
if(c=='M')
f1[1][1]=i,f1[1][2]=j,v1[i][j]=1;
if(c=='G')
f2[1][1]=i,f2[1][2]=j,v2[i][j]=1;
}
}
bfs();
}
}