HDOJ3085 Nightmare II 双向BFS

Posted jackpei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ3085 Nightmare II 双向BFS相关的知识,希望对你有一定的参考价值。

重构一遍就A了。。。但这样效率太低了。。。莫非都要重构???QWQ


 

每一秒男同志bfs3层,女同志bfs1层。注意扩展状态时,要判一下合不合法再扩展,而不是只判扩展的状态合不合法,否则有可能由非法的走到合法的地方。

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define R register int
const int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
using namespace std;
inline int g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==-?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m,t,tim,cc;
int gx,gy,mx,my,zx,zy,zx1,zy1;
char e[810][810];
inline int abs(int x) {return x>0?x:-x;}
inline bool is(char ch) {return ch==X||ch==Z||ch==M||ch==G||ch==.;}
inline bool ckpos(int x,int y) {
    if(x<1||x>n||y<1||y>m||e[x][y]==X) return false;
    if(2*tim>=abs(x-zx)+abs(y-zy)||2*tim>=abs(x-zx1)+abs(y-zy1)) return false;
    return true;
}
struct node{int x,y; node() {}
    node(int xx,int yy) {x=xx,y=yy;}
};
queue<node>q,q1;
inline bool bfs() {
    for(R x=1;x<=3;++x) { queue<node> qt=q; R sz=q.size();
        while(sz--) {
            node u=qt.front(); qt.pop(); R x=u.x,y=u.y;
            if(!ckpos(x,y)) continue;
            for(R i=0;i<4;++i) {
                R xx=x+dx[i],yy=y+dy[i];
                if(!ckpos(xx,yy)||e[xx][yy]==M) continue;
                if(e[xx][yy]==G) return true; e[xx][yy]=M;
                qt.push(node(xx,yy));
            }
        } q=qt;
    } return false;
}
inline bool bfs1() { queue<node> qt=q1; R sz=q1.size();
    while(sz--) {
        node u=qt.front(); qt.pop(); R x=u.x,y=u.y;
        if(!ckpos(x,y)) continue;
        for(R i=0;i<4;++i) {
            R xx=x+dx[i],yy=y+dy[i];
            if(!ckpos(xx,yy)||e[xx][yy]==G) continue;
            if(e[xx][yy]==M) return true; e[xx][yy]=G;
            qt.push(node(xx,yy));
        }
    } q1=qt; return false;
}
signed main() {
    t=g(); while(t--) { tim=0; cc=0;
        n=g(),m=g();
        for(R i=1;i<=n;++i) for(R j=1;j<=m;++j) {
            while(!is(e[i][j]=getchar())); if(e[i][j]==M) mx=i,my=j;
            else if(e[i][j]==G) gx=i,gy=j;
            else if(e[i][j]==Z) if(cc) zx1=i,zy1=j; else zx=i,zy=j,++cc;
        } while(q.size()) q.pop(); while(q1.size()) q1.pop();
        q.push(node(mx,my)); q1.push(node(gx,gy));
        while(++tim) {
            if(bfs()||bfs1()) {printf("%d\n",tim); break;}
            if(q1.empty()||q.empty()) {printf("-1\n"); break;}
        }
    }
}

2019.04.27

以上是关于HDOJ3085 Nightmare II 双向BFS的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3085 Nightmare Ⅱ 双向BFS

HDU3085nightmare2 双向BFS

HDU 3085 - Nightmare Ⅱ - []

[HDU3085] Nightmare Ⅱ 题解

HDU3085 Nightmare Ⅱ

kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085