HDU 1072 Nightmare BFS

本文介绍了一种使用广度优先搜索(BFS)解决迷宫问题的方法,通过跟踪每一步的剩余步数来寻找从起点到终点的最短路径,并特别讨论了遇到特殊点(值为4)时的处理方式。

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

题意:在 NM 的矩阵内只可以走六步,如果碰到4就可以再走六步,问能不能走出迷宫?(如果能走出,输出最少的秒数,如果不能走出,输出-1。)
思路:BFS呀,我开始蠢,写了DFS。建一个t数组, tij 代表走到 (i,j) 还剩几步可以走,如果碰到4的话,设置一个时间,重新加入队列即可。

http://acm.hdu.edu.cn/showproblem.php?pid=1072

/*********************************************
    Problem : HDU 1072
    Author  : NMfloat
    InkTime (c) NM . All Rights Reserved .
********************************************/

#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

#define rep(i,a,b)  for(int i = (a) ; i <= (b) ; i ++)
#define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --)
#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next)
#define cls(a,x)   memset(a,x,sizeof(a))
#define eps 1e-8

using namespace std;

const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5+5;
const int MAXE = 2e5+5;

struct Node {
    int x,y,t;//t代表走到这一秒最少的时间
    int cost;//消耗的时间
    Node(){}
    Node(int _x,int _y,int _t,int _cost){x = _x ; y = _y ; t = _t;cost = _cost;}
};

typedef long long LL;
typedef unsigned long long ULL;

int T,n,m,k;

queue<Node>q;

int fx[] = {0,1,-1,0,0};
int fy[] = {0,0,0,-1,1};
int sx,sy;
int Map[10][10];
int t[10][10];//走到这一步最短的时间
int ok ;

void BFS() {
    while(!q.empty()) q.pop();
    q.push(Node(sx,sy,6,0));
    t[sx][sy] = 6;
    while(!q.empty()) {

        Node tmp = q.front();
        q.pop();
        // printf("x : %d y : %d tmp : %d cost : %d\n",tmp.x,tmp.y,tmp.t,tmp.cost);
        if(tmp.t == 0) continue;
        if(Map[tmp.x][tmp.y] == 3) {
            ok = 1;
            printf("%d\n",tmp.cost);
            break;
        }
        rep(i,1,4) {
            int tmpx = tmp.x + fx[i];
            int tmpy = tmp.y + fy[i];
            int tmpt = tmp.t - 1;
            if(tmpx >= 1 && tmpx <= n && tmpy >= 1 && tmpy <= m) {
                if(t[tmpx][tmpy] < tmpt) {
                    t[tmpx][tmpy] = tmpt;
                    if(Map[tmpx][tmpy] == 1 || Map[tmpx][tmpy] == 3) {
                        q.push(Node(tmpx,tmpy,tmp.t-1,tmp.cost+1));
                    }
                    else if(Map[tmpx][tmpy] == 4) {
                        t[tmpx][tmpy] = 6;
                        q.push(Node(tmpx,tmpy,6,tmp.cost+1));
                    }
                }
            }
        }
    }
}

void input() {
    scanf("%d %d",&n,&m);
    rep(i,1,n) rep(j,1,m) {
        scanf("%d",&Map[i][j]);
        if(Map[i][j] == 2) {
            sx = i ; sy = j;
        }
    }    
}

void solve() {
    cls(t,0);
    ok = 0;
    BFS();
    if(!ok) puts("-1");
}

int main(void) {
    //freopen("a.in","r",stdin);
    scanf("%d",&T); while(T--) {
    //while(~scanf("%d %d",&n,&m)) {
    //while(scanf("%d",&n),n) {
        input();
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值