HDU 1226 胜利大逃亡(续)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429

代码如下。

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#include <cstring>
#include <cassert>
using namespace std;

typedef long long ll;
const int maxn=55555;
const int INF=0x7fffffff;
const int mod=1e7+7;
#define LSON l, m, rt<<1
#define RSON m+1, r, rt<<1|1
#define ESP 1e-7

struct point {
    int x, y, keys;
}Start, End;

char _map[22][22];
int vis[22][22][1111];//记录到点(i, j)有k个钥匙的步数。k用二进制进行压缩,总共最多十把钥匙,所以数组开过1024即可。
int xx[4]= {1, 0, -1, 0};
int yy[4]= {0, 1, 0, -1};
int n, m, t;

int BFS(point s, point e) {
    memset(vis, 0, sizeof(vis));
    queue<point> q;
    q.push(s);
    vis[s.x][s.y][s.keys]=1;
    while(!q.empty()) {
        point ff=q.front();
        q.pop();
        if(vis[ff.x][ff.y][ff.keys]-1>=t)//如果超过时间,去掉
            continue;
        if(ff.x==e.x && ff.y==e.y)//到达终点结束
            return vis[ff.x][ff.y][ff.keys]-1;//因为起点的步数当为1
        for(int i=0;i<4;i++) {
            point pi;
            int xi=pi.x=ff.x+xx[i];
            int yi=pi.y=ff.y+yy[i];
            pi.keys=ff.keys;
            if(xi>=1 && xi<=n && yi>=1 && yi<=m && _map[xi][yi]!='*' && !vis[xi][yi][pi.keys]) {
                if(_map[xi][yi]>='a' && _map[xi][yi]<='j') {
                    int key=1<<(_map[xi][yi]-'a');
                    pi.keys=ff.keys|key;//添加钥匙
                    vis[xi][yi][pi.keys]=vis[ff.x][ff.y][ff.keys]+1;
                    q.push(pi);
                }
                else if(_map[xi][yi]=='.') {
                    vis[xi][yi][pi.keys]=vis[ff.x][ff.y][ff.keys]+1;
                    q.push(pi);
                }
                else {
                    int lock=1<<(_map[xi][yi]-'A');
                    if(lock&ff.keys) {//判断是否有该把钥匙
                        vis[xi][yi][pi.keys]=vis[ff.x][ff.y][ff.keys]+1;
                        q.push(pi);
                    }
                }
            }
        }
    }
    return -1;
}

int main() {
    while(~scanf("%d%d%d", &n, &m, &t)) {
        getchar();
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                scanf("%c", &_map[i][j]);
                if(_map[i][j]=='@') {
                    Start.x=i;
                    Start.y=j;
                    Start.keys=0;
                    _map[i][j]='.';
                }
                else if(_map[i][j]=='^') {
                    End.x=i;
                    End.y=j;
                    End.keys=0;
                    _map[i][j]='.';
                }
            }
            getchar();
        }
        printf("%d\n", BFS(Start, End));
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值