HDU2102 A计划(BFS)

本文介绍了一种解决双层迷宫问题的BFS算法实现。重点在于判断当前格子是否可以从一层移动到另一层,同时确保非障碍物格子能够进行上下左右的移动。通过使用结构体节点和队列实现了有效的搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题

比较坑的就是讨论从本格子向另一层走还是本层左右上下移动。并不是所有从队列出来的格子都能进行上下左右移动的,只有非‘#’格子才能。

注意这一点后,就是一个常规的BFS了。

AC代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=12;
char g[2][maxn][maxn];
struct node
{
    int z;//在第0层还是第1层
    int x,y;//坐标
    int t;//时间
    node(int z,int x,int y,int t):z(z),x(x),y(y),t(t){}
};
int n,m,limit;
int si,sj,sk,ei,ej,ek;
bool vis[2][maxn][maxn];
bool valid(int x,int y,int z)
{
    return x>=0 && x<n && y>=0 && y<m && g[z][x][y]!='*';
}
int dir[4][2]={0,1,0,-1,1,0,-1,0};
void bfs()
{
    memset(vis,false,sizeof(vis));
    queue<node> Q;
    vis[sk][si][sj]=true;
    Q.push(node(sk,si,sj,0));
    while(!Q.empty())
    {
        node now=Q.front();Q.pop();
        int z=now.z,x=now.x,y=now.y,t=now.t;
        if(x==ei && y==ej && z==ek && t<=limit)
        {
            printf("YES\n");
            return ;
        }

        if(g[z][x][y]=='#' && g[z^1][x][y]!='*' && g[z^1][x][y]!='#' && !vis[z^1][x][y])
        {
            vis[z^1][x][y]=true;
            Q.push(node(z^1,x,y,t));
        }
        if(g[z][x][y]!='#')//注意别忘了,WA了几次在这里
            for(int i=0; i<4; i++)
            {
                int fx=x+dir[i][0],fy=y+dir[i][1];
                if(!valid(fx,fy,z) || vis[z][fx][fy])
                    continue;
                vis[z][fx][fy]=true;
                Q.push(node(z,fx,fy,t+1));
            }
    }
    printf("NO\n");
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&limit);
        for(int i=0;i<n;i++)
            scanf("%s",g[0][i]);
        for(int i=0;i<n;i++)
            scanf("%s",g[1][i]);

        for(int k=0;k<2;k++)
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(g[k][i][j]=='S')
                si=i,sj=j,sk=k;
            if(g[k][i][j]=='P')
                ei=i,ej=j,ek=k;
        }
        bfs();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值