HDU 1429 胜利大逃亡(续)

本文介绍了一道使用广度优先搜索(BFS)解决迷宫最短路径问题的题目。通过状态压缩记录钥匙获取情况,实现了寻找解锁并逃离迷宫的最短步数。

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

做了一些关于BFS的题目,每个题目的描述不一样,但是特点都是移动时状态的改变。这道题主要就是找到最短路径上的锁的钥匙,解锁并出逃。当前是否拥有特定锁的钥匙的状态可以用二进制压缩的方法记录。初次接触状态压缩,对它的原理还有待进一步的了解,现在只是模仿大神的方法试敲。

ps:这道题之前一直CE,原因是命名空间中的next关键字和我自己定义的变量冲突,浪费了不少时间,下次切记避免这种问题。
http://acm.hdu.edu.cn/showproblem.php?pid=1429

#include<cstdio>
#include<cstring>
#include<queue>
#define MAX 21
using namespace std;

char maze[MAX][MAX];
bool flag[MAX][MAX][1024];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int n, m, t;
struct P{
    short x, y, step, key;
    bool legal(){
        if(x >= 0 && x < n && y >= 0 && y < m)
            return true;
        return false;
    }
}s, next1;

int bfs(){
    memset(flag, false, sizeof(flag));
    queue<P> que;
    que.push(s);
    while(!que.empty()){
        P p = que.front();
        que.pop();
        for(int i = 0;i < 4;i++){
            next1 = p;
            next1.x = p.x + dir[i][0];
            next1.y = p.y + dir[i][1];
            next1.step++;
            if(next1.step >= t)
                break;
            if(next1.legal() && maze[next1.x][next1.y] != '*'){
                if(maze[next1.x][next1.y] == '^')
                    return next1.step;
                if(maze[next1.x][next1.y] >= 'A' && maze[next1.x][next1.y] <= 'J'){
                    if((1<<(maze[next1.x][next1.y] - 'A'))&next1.key && flag[next1.x][next1.y][next1.key] == false){
                        que.push(next1);
                        flag[next1.x][next1.y][next1.key] = true;
                    }
                }
                else if(maze[next1.x][next1.y] >= 'a' && maze[next1.x][next1.y] <= 'j'){
                    next1.key |= (1<<(maze[next1.x][next1.y] - 'a'));
                    if(flag[next1.x][next1.y][next1.key] == false){
                        que.push(next1);
                        flag[next1.x][next1.y][next1.key] = true;
                    }
                }
                else{
                    if(!flag[next1.x][next1.y][next1.key]){
                        que.push(next1);
                        flag[next1.x][next1.y][next1.key] = true;
                    }
                }
            }
        }
    }
    return -1;
}
main(){
    while(~scanf("%d %d %d", &n, &m, &t)){
        getchar();
        for(int i = 0;i < n;i++){
            gets(maze[i]);
        }
        for(int i = 0;i < n;i++){
            for(int j = 0;j < m;j++){
                if(maze[i][j] == '@'){
                    s.x = i;
                    s.y = j;
                    s.key = 0;
                    s.step = 0;
                }
            }
        }
        int res = bfs();
        printf("%d\n",res);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值