I - A计划[bfs]

I - A计划

题意大概是,一个漂亮可爱的公主被关在了一个两层的魔堡里面。在魔堡里面呢有墙(*),路(.),传送机(#)。一群有勇有谋的勇士来找公主,但是时间有限。墙不能走。每走一个都需要花一分钟的时间。而如若走到传送机上,则会自动传到下一层(第一层到第二层,第二层到第一层),若传到墙就亮了。问你能不能在给定时间内找到我们漂亮可爱的公主。

脑洞:让我想到那个三维空间的迷宫,其实就是一个简单的bfs,但要注意细节。
1.传送机如果传送过去还是传送机,那这个传送机不能走。(不然就陷入无限传送?)
2.在写bfs的时候,注意传送过去可以是路,也可以直接将公主拥入怀中。
3.在标记数组的时候,要判断传送过去的那个点,是不是已经走过了,即要判断传送机和传送过去的点两个点是否走过。
4.有可能公主被关在密闭的小空间里,这种情况也要输出NO。

还有就是这道题教会我一点(也可能是我这天脑子有点混),像这种一定有输出的题目,即要么可以要么不可以,一定要注意是不是每一种情况都输出了。

struct node {
    int x,y,level;
    int step;
};

char m[len][len][2];
int vis[len][len][2];
int dv[4][2] = {{0,1}, {1,0}, {-1,0}, {0,-1}};
queue <struct node> q;
struct node head;
int N,M,T,n;
int Px, Py, Plvl;
int main(){
    cin >> n ;
    while (n--) {
        cin >> N >> M >> T;
        Init();
        bfs();
        //cout << "!!!" << Px << " " << Py << " " << Plvl << endl;
    }
    
    return 0;
}
void Init(){
    while (!q.empty()) {
        q.pop();
    }
    
    memset(m, '.', sizeof(m));
    memset(vis, 0, sizeof(vis));
    
    for (int i=0; i<2; i++){
        for (int j=0; j<N; j++){
            for (int p=0; p<M; p++){
                cin >> m[j][p][i];
                if (m[j][p][i] == 'P'){
                    Px = j; Py = p; Plvl = i;
                }
            }
        }
    }
    
    struct node tmp;
    tmp.x = 0; tmp.y = 0; tmp.step = 0;tmp.level = 0;
    q.push(tmp);
    vis[0][0][0] = 1;
    
}
void bfs(){
    while (!q.empty()) {
        head = q.front();q.pop();
        //cout << head.x << " " << head.y << " " << head.level << "    " << head.step << endl;
        
        if (head.step > T) {
            cout << "NO" << endl;
            return;
        }//队内的成员的步数比T大,说明已经救不到了
        
        if (head.x == Px && head.y == Py && head.level == Plvl){
            cout << "YES" << endl;
            return;
        }
        
        for (int i=0; i<4; i++){
            int _x = head.x + dv[i][0];
            int _y = head.y + dv[i][1];
            
            if (_x<0 || _x>=N || _y<0 || _y>=M) continue;
            if (m[_x][_y][head.level] == '*') continue;
            if (vis[_x][_y][head.level] != 0) continue;
            
            struct node tmp;
            tmp.x = _x; tmp.y = _y; tmp.step = head.step + 1;
            
            if (m[_x][_y][head.level] == '#'){
                if ((m[_x][_y][1-head.level] == 'P' || m[_x][_y][1-head.level] == '.')&& vis[_x][_y][1-head.level] == 0){//这里错了好几次。。。
                    tmp.level = 1 - head.level;
                    q.push(tmp);
                    vis[_x][_y][tmp.level] ++;
                }
            }else {
                tmp.level = head.level;
                q.push(tmp);
                vis[_x][_y][tmp.level] ++;
            }
            
        }
        
    }
    cout << "NO" << endl;//别忘了
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值