HDU 3085 双BFS

题意:在迷宫里有两个人,一个三步,一个一步,还有两个鬼 每秒占距离为2的格子而且不停扩散。

题解:双BFS。可以用参数传递的方式写一个BFS,但是如果只是双BFS直接写两个函数比较好。

对于步数可以大于一步的情况,可以在外层用step,一层一层来。

不要忘了传递队列。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
char mp[805][805];
int n,m,cnt,step;
int gx,gy,mx,my;
struct node {
    int x,y;
}a,g[2];
queue <node > que1,que2,que;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int myabs(int x){
    if (x>0)return x;
    return -x;
}
int dis(node a){
    int temp;
    temp=myabs(a.x-g[0].x)+myabs(a.y-g[0].y);
    temp=min(temp,myabs(a.x-g[1].x)+myabs(a.y-g[1].y));
    return temp;
}
int check(node p){
        if(p.x>=n||p.y>=m||p.x<0||p.y<0)return 1;
        if(dis(p)<=2*step)return 1;//检查距离
        if(mp[p.x][p.y]=='X')return 1;
        return 0;
}
int m_bfs(){//m的广搜
    node next;
    int i,j;
    que=que1;
    for(i=0;i<3;i++){
        while(!que.empty()){
            a=que.front();
            que.pop();
            que1.pop();
            if(check(a))continue;
            for(j=0;j<4;j++){
                next.x=a.x+dir[j][0];
                next.y=a.y+dir[j][1];
                if(check(next))continue;
                if(mp[next.x][next.y]=='M')continue;
                if(mp[next.x][next.y]=='G')return 1;
                mp[next.x][next.y]='M';
                que1.push(next);
            }
        }
        que=que1;//传递
    }
    return 0;
}
int g_bfs(){//g的广搜
    int i,j;
    node next;
    que=que2;
    while(!que.empty()){
        a=que.front();
        que.pop();
        que2.pop();
        if(check(a))continue;
        for(i=0;i<4;i++){
            next.x=a.x+dir[i][0];
            next.y=a.y+dir[i][1];
            if(check(next))continue;
            if(mp[next.x][next.y]=='G')continue;
            if(mp[next.x][next.y]=='M')return 1;
            mp[next.x][next.y]='G';
            que2.push(next);
        }
    }
    return 0;
}
void in_it(){

	while(!que.empty())que.pop();
	while(!que1.empty())que1.pop();
	while(!que2.empty())que2.pop();
    int i,j,cnt=0;//初始化
    for(i=0;i<n;i++)scanf("%s",mp[i]);//用cin和%c 都会超时
    for(i=0;i<n;i++){
        for(j=0;j<m;j++){
            if(mp[i][j]=='M')mx=i,my=j;
            if(mp[i][j]=='G')gx=i,gy=j;
            if(mp[i][j]=='Z') g[cnt].x=i,g[cnt++].y=j;
        }
    }
}
int main(){
int i,j;
    int f1,f2;
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        in_it();
        step=0;
        a.x=mx,a.y=my;
        que1.push(a);
        a.x=gx,a.y=gy;
        que2.push(a);
        int flag=-1;
        while(!que1.empty()&&!que2.empty()){
            step++;//一步一步来
            f1=m_bfs();
            f2=g_bfs();
            if(f1||f2){
                flag=step;
                break;
            }
        }
       /* for(i=1;i<=n;i++){
		for(j=1;j<=m;j++)printf("%c",mp[i][j]);
		printf("\n");
        }*/
        printf("%d\n",flag);
    }
}

猜你喜欢

转载自blog.csdn.net/nwpu2017300135/article/details/80499544