YbtOJ 广度搜索课堂过关 例6 逃离噩梦【bfs】

题目

在这里插入图片描述


思路

这道题我们需要男生女生同时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...
*/

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/112973067