题目
思路
这道题我们需要男生女生同时bfs,
恶魔的扩张直接用曼哈顿距离和扩张时间来 O ( 1 ) O(1) O(1) 判断即可。
男生的bfs因为有三步,所以我们需要把当前扩散到的所有点继续扩散直到3步全部扩散完。
其余的地方就照常即可,注意本题有很多细节,只可意会不可言传☺
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int dx[5]={
0,0,1,0,-1};
const int dy[5]={
0,1,0,-1,0};
int t,n,m,a[810][810],w,em[2][2],ce;
int f1[656101][3],f2[656101][3];
int v1[810][810],v2[810][810];
char c;
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;
}
bool check1(int a,int b,int js)
{
int emm=abs(em[0][0]-a)+abs(em[0][1]-b);
if(emm<=js*2)
return 0;
else
{
int emm2=abs(em[1][0]-a)+abs(em[1][1]-b);
if(emm2<=js*2)
return 0;
else
return 1;
}
}
bool check2(int a,int b,int js)
{
int emm=abs(em[0][0]-a)+abs(em[0][1]-b);
if(emm<=js*2)
return 0;
else
{
int emm2=abs(em[1][0]-a)+abs(em[1][1]-b);
if(emm2<=js*2)
return 0;
else
return 1;
}
}
void bfs()
{
int hd=0,tl=1,ans=0,hd2=0,tl2=1,ss1=0,ss2=1,kk1=0,kk2=1;
for(int js=1; hd!=tl||hd2!=tl2; js++)
{
for(int i=1; i<=3; i++)
for(int j=abs(ss2-ss1); j!=0; j--)
{
hd=hd%656100+1;
ss1++;
for(int tz=1; tz<=4; tz++)
{
int xx=f1[hd][1]+dx[tz];
int yy=f1[hd][2]+dy[tz];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&v1[xx][yy]==0&&a[xx][yy]!=-1&&a[xx][yy]!=1&&check1(xx,yy,js)&&check1(f1[hd][1],f1[hd][2],js))
{
// cout<<xx<<' '<<yy<<endl;
tl=tl%656100+1;
ss2++;
f1[tl][1]=xx;
f1[tl][2]=yy;
v1[xx][yy]=1;
if(v2[xx][yy]==1)
{
cout<<js<<endl;
return;
}
}
}
}
for(int kk=kk2-kk1; kk!=0; kk--)
{
hd2=hd2%656100+1;
kk1++;
for(int j=1; j<=4; j++)
{
int xx=f2[hd2][1]+dx[j];
int yy=f2[hd2][2]+dy[j];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&v2[xx][yy]==0&&a[xx][yy]!=-1&&a[xx][yy]!=1&&check2(xx,yy,js)&&check2(f2[hd2][1],f2[hd2][2],js))
{
//cout<<xx<<' '<<yy<<endl;
tl2=tl2%656100+1;
kk2++;
f2[tl2][1]=xx;
f2[tl2][2]=yy;
v2[xx][yy]=1;
if(v1[xx][yy]==1)
{
cout<<js<<endl;
return;
}
}
}
}
}
cout<<-1<<endl;
return;
}
int main()
{
t=read();
while(t--)
{
memset(v1,0,sizeof(v1));
memset(v2,0,sizeof(v2));
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
memset(a,0,sizeof(a));
ce=0;
cin>>n>>m;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
c=getchar();
while(c!='X'&&c!='.'&&c!='Z'&&c!='G'&&c!='M')
c=getchar();
if(c=='X')
a[i][j]=-1;
if(c=='Z'&&ce==0)
em[0][0]=i,em[0][1]=j,ce++,a[i][j]=1;
if(c=='Z'&&ce==1)
em[1][0]=i,em[1][1]=j,a[i][j]=1;
if(c=='G')
f2[1][1]=i,f2[1][2]=j,v2[i][j]=1;
if(c=='M')
f1[1][1]=i,f1[1][2]=j,v1[i][j]=1;
}
bfs();
}
}
/*
153
7 6
......
....G.
......
M.....
......
..Z...
..Z...
*/