zoukankan      html  css  js  c++  java
  • [题解](双向bfs)hdu_3085_Nightmare Ⅱ

    发现直接搜索比较麻烦,但是要同时两个人一起走容易想到双向bfs,比较普通,

    在判断是否碰到ghost时只要比较两点的曼哈顿距离大小和step*2(即ghost扩散的距离)即可,仔细思考也是可以想到的

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int maxn=809;
    struct node{
        int x,y;
        node(){}
        node(int a,int b){
            x=a,y=b;
        }
    }mon[2];
    queue<node>pq[2];
    int n,m;
    char maze[maxn][maxn];
    int used[2][maxn][maxn];
    int dx[]={1,-1,0,0};
    int dy[]={0,0,1,-1};
    int step;
    int check(node a){
        if(a.x<0 || a.y<0 || a.x>=n || a.y>=m)return 0;
        if(maze[a.x][a.y]=='X')return 0;
        if((abs(a.x-mon[0].x)+abs(a.y-mon[0].y))<=2*step)return 0;
        if((abs(a.x-mon[1].x)+abs(a.y-mon[1].y))<=2*step)return 0;
        return 1;
    }
    int bfs(int w){
    //    while(!pq[w].empty()){
        int sum = pq[w].size();//这里不能搜完 
        while (sum--){
            int x=pq[w].front().x,y=pq[w].front().y;pq[w].pop();
            if(!check(node(x,y)))continue;
            for(int i=0;i<4;i++){
                int xx=x+dx[i],yy=y+dy[i];
                if(!check(node(xx,yy)))continue;
                if(!used[w][xx][yy]){
                    if(used[w^1][xx][yy]==1)return 1;
                    used[w][xx][yy]=1;
                    pq[w].push(node(xx,yy));
                }
            }
        }
        return 0;
    }
    int ax,ay,bx,by;
    int solve(){
        while(!pq[0].empty())pq[0].pop();
        while(!pq[1].empty())pq[1].pop();
        pq[0].push(node(ax,ay));
        pq[1].push(node(bx,by));
        memset(used,0,sizeof(used));
        used[0][ax][ay]=used[1][bx][by]=1;
        step=0;
        while(!pq[0].empty() || !pq[1].empty()){
            step++;
            if(bfs(0)==1)return step;
            if(bfs(0)==1)return step;
            if(bfs(0)==1)return step;
            if(bfs(1)==1)return step;
        }
        return -1;
    }
    int main(){int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            int cnt=0;
            for(int i=0;i<n;i++)scanf("%s",maze[i]);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(maze[i][j]=='G')
                    bx=i,by=j;
                    else if(maze[i][j]=='M')
                    ax=i,ay=j;
                    else if(maze[i][j]=='Z')
                    mon[cnt].x=i,mon[cnt++].y=j;
                }
            }
            printf("%d
    ",solve());
        }
        
    }
  • 相关阅读:
    [bzoj3295][Cqoi2011][动态逆序对] (树套树)
    [bzoj3209][花神的数论题] (数位dp+费马小定理)
    [bzoj1026][SCOI2009][windy数] (数位dp)
    [bzoj4521][Cqoi2016][手机号码] (数位dp+记忆化搜索)
    [bzoj1833][ZJOI2010][count] (数位dp)
    [spoj1182][Sorted Bit Sequence] (数位dp)
    [ural1057][Amount of Degrees] (数位dp+进制模型)
    [hdu3652][B-number] (数位dp)
    【bzoj2523】【CTSC2001】聪明的学生
    友情链接(有的是单向的)
  • 原文地址:https://www.cnblogs.com/superminivan/p/10858739.html
Copyright © 2011-2022 走看看