假设在t时刻,erriyue和他的girl相遇,那么如果此时他们中任何一人与魔鬼的曼哈顿距离小于2*t,即魔鬼能够走的路程,那么他们将在相遇前被魔鬼吃掉,反之则可以相遇。
详见代码:
/*************************************************************************
> File Name: main.cpp
> Author:Eagles
> Mail:None
> Created Time: 2018年08月31日 星期五 22时00分45秒
> Description:HDU3085
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define N 800
int vis[2][N][N];
char maze[N][N];//迷宫
int len,n,step;//n和len表示迷宫的高和宽,step表示时间
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct node
{
int x,y;
int step;
}m,g,z[2],cur,nex;//cur为当前,nex为移动一步之后
queue<node>Q[2];
bool check(node a)
{
if (a.x<0||a.x>=n||a.y<0||a.y>=len||maze[a.x][a.y]=='X')
return false;
for (int i=0; i<2; i++)
{
if (abs(a.x-z[i].x)+abs(a.y-z[i].y)<=2*step)
return false;
}
return true;
}
bool bfs(int num)
{
int the_size=Q[num].size();
for (int i=0; i<the_size; i++)
{
cur=Q[num].front();
Q[num].pop();
if (!check(cur))//如果魔鬼能够吃掉,说明这个不行
continue;
for (int i=0; i<4; i++)
{
nex=cur;
nex.x+=dir[i][0];
nex.y+=dir[i][1];
if (!check(nex))
continue;
if (!vis[num][nex.x][nex.y])
{
if (vis[num^1][nex.x][nex.y])//如果另一个人来过这里
return true;
vis[num][nex.x][nex.y]=true;
Q[num].push(nex);
}
}
}
return false;
}
int solve()
{
for (int i=0; i<2; i++)//清空队列
{
while (!Q[i].empty())
Q[i].pop();
}
memset(vis,false,sizeof(vis));
Q[0].push(m);
Q[1].push(g);
vis[0][m.x][m.y]=true;
vis[1][g.x][g.y]=true;
step=0;
while (!Q[0].empty()||!Q[1].empty())
{
step++;
if (bfs(0))//以下为走三步,如果其中一个可行,则可行
return step;
if (bfs(0))
return step;
if (bfs(0))
return step;
if (bfs(1))//girl走一步
return step;
}
return -1;
}
void init()
{
memset(maze,'\0',sizeof(maze));
int flag=0;
scanf("%d%d",&n,&len);
for (int i=0; i<n; i++)
{
scanf("%s",maze[i]);
for (int j=0; j<len; j++)
{
if (maze[i][j]=='M')
{
m.x=i;
m.y=j;
}
if (maze[i][j]=='G')
{
g.x=i;
g.y=j;
}
if (maze[i][j]=='Z')
{
z[flag].x=i;
z[flag++].y=j;
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
init();
printf("%d\n",solve());
}
return 0;
}