逃离噩梦


解题思路

双向bfs
建立两个队列
男孩一个,女孩一个
同时开始bfs
然后注意判断鬼到不到的了
如果男孩女孩会和
当前轮数为最短时间

AC代码

#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
int o,n,m,tot,head1,tail1,head2,tail2,pxm[640005],pym[640005],pxg[640005],pyg[640005],pxz[5],pyz[5],c[805][805];
char a[805][805];
int dx[4]={
   0,0,1,-1};
int dy[4]={
   1,-1,0,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;
}
bool check(int x,int y,int z)//判断
{
   
	if(x<1||x>n||y<1||y>m)return false;//出界
	if(a[x][y]=='X')return false;//墙
	for(int i=1;i<=tot;i++)//鬼到不到的了
	 if(abs(x-pxz[i])+abs(y-pyz[i])<=2*z)return false;
	return true;
}
void bfs()
{
   
	while(head1<tail1&&head2<tail2)
	{
   
		o++;
		for(int times=1;times<=3;times++)//3次(男孩)
		{
   
			int end=tail1;
			while(head1<end)
			{
   
				head1++;
				if(!check(pxm[head1],pym[head1],o))continue;
				for(int i=0;i<4;i++)
				{
   
					int xx=pxm[head1]+dx[i],yy=pym[head1]+dy[i];
					if(check(xx,yy,o))
					 if(c[xx][yy]!=1)
					 {
   
					 	if(c[xx][yy]==2){
   printf("%d\n",o);return;}//会和就输出
					 	c[xx][yy]=1;
					 	pxm[++tail1]=xx;pym[tail1]=yy;
					 }
				}
			}
		}
		int end=tail2;//一次(女孩)
		while(head2<end)
		{
   
			head2++;
			if(!check(pxg[head2],pyg[head2],o))continue;
			for(int i=0;i<4;i++)
			{
   
				int xx=pxg[head2]+dx[i],yy=pyg[head2]+dy[i];
				if(check(xx,yy,o))
				 if(c[xx][yy]!=2)
				 {
   
				 	if(c[xx][yy]==1){
   printf("%d\n",o);return;}//会和就输出
				 	c[xx][yy]=2;
				 	pxg[++tail2]=xx;pyg[tail2]=yy;
				 }
			}
		}
	}
	printf("-1\n");
	return;
}
int main()
{
   
	int T;
	T=read();
	while(T--) 
	{
   
		o=tot=head1=tail1=head2=tail2=0;//初值
		memset(c,0,sizeof(c));
		n=read();
		m=read();
		for(int i=1;i<=n;i++)//输入
	 	 for(int j=1;j<=m;j++)
	 	 {
   
	 		a[i][j]=getchar();
	 		while(a[i][j]!='.'&&a[i][j]!='X'&&a[i][j]!='Z'&&a[i][j]!='G'&&a[i][j]!='M')
	 	 	 a[i][j]=getchar();
	 		if(a[i][j]=='M'){
   pxm[++tail1]=i;pym[tail1]=j;c[i][j]=1;}
	 		if(a[i][j]=='G'){
   pxg[++tail2]=i;pyg[tail2]=j;c[i][j]=2;}
	 		if(a[i][j]=='Z'){
   pxz[++tot]=i;pyz[tot]=j;}
	 	 }
		bfs();
	}
	return 0;
}

谢谢