hdu1429 胜利大逃亡(续) 【BFS】+【状态压缩】

 <题目链接>

题目大意:

一个人从起点走到终点,问他是否能够在规定的时间走到,在走向终点的路线上,可能会有一些障碍门,他需要在路上捡到开门的对应钥匙,才能通过这扇门。如果他到达终点的时间超过了规定时间,或者他根本就走不到终点,输出-1,否则的话,输出他走的步数。

解题思路:

此题与普通的bfs类似,只不过到下一个点的时候,要加上一些判断,如果是钥匙,则将它储存起来,如果是门,则判断是否已经捡到了对应的钥匙,如果有对应钥匙,则这个门与其它 '.' 无异,如果没有对应的钥匙,则不能通过。这个功能是由状态压缩来实现的,将钥匙的对应序号转化成二进制,方便钥匙的存储和判断。另外,还有一个需要注意的就是vis数组的设置,此题只要仔细思考就会发现,设置成二维的显然不行,因为走过的路是可以重复走的,只不过你钥匙的数量要增加,比如说,你走到了一扇门那里,但是你没有钥匙,你只好向别的方向继续搜索,当你捡到对应的钥匙后,可以沿着原路返回到那扇门那里。因此,为了满足题目意思,又不需要走太多重复的路,这样的设置还是挺合理的。

 

#include <bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define rep(i,s,t) for(int i=s;i<t;i++)
const int N = 25;
int vis[N][N][1028];            //1<<10=1024,加一维走到这个点带钥匙的状态
char g[N][N];
int dir[][2]={1,0,0,1,-1,0,0,-1};
int n,m,t;

struct Node{
    int x,y,key,step;
    Node(int _x=0, int _y=0, int _key=0, int _step=0): x(_x), y(_y), key(_key), step(_step){}
};
queue<Node>q;

int bfs() {
    Node s, now, next;
    while(!q.empty()) {
        now=q.front();q.pop();
        if(g[now.x][now.y] == '^') {
            if(now.step < t) return now.step;
        }
        rep(i,0,4) {    //往4个方向走
            int nx = now.x + dir[i][0];
            int ny = now.y + dir[i][1];
            if(nx < 0 || nx >=n || ny < 0 || ny >= m || g[nx][ny] == '*') continue;
            else if((g[nx][ny] == '.' || g[nx][ny] == '^') && !vis[nx][ny][now.key]) {
                vis[nx][ny][now.key]=1;
                next.x = nx, next.y = ny;
                next.step = now.step + 1, next.key = now.key;
                q.push(next);
            } else if(g[nx][ny] >= 'A' && g[nx][ny] <= 'J' && !vis[nx][ny][now.key]) {
                int key = 1 << (g[nx][ny] - 'A');
                if(now.key & key) {        //如果之前取得了这扇门的钥匙
                    vis[nx][ny][now.key] = 1;
                    next.x = nx, next.y = ny;
                    next.step = now.step + 1;
                    next.key = now.key;
                    q.push(next);
                }
            } else if(g[nx][ny] >= 'a' && g[nx][ny] <= 'j' && !vis[nx][ny][now.key]) {
                int key = 1 << (g[nx][ny] - 'a');
                vis[nx][ny][now.key] = 1;
                next.x = nx; next.y = ny;
                next.step = now.step + 1;
                next.key = now.key | key;
                q.push(next);
            }
        }
    }
    return -1;
}
int main(){
    while(~scanf("%d%d%d", &n,&m,&t)) {
        while(!q.empty()) q.pop();
        clr(vis,0);
        Node s;
        rep(i,0,n) {
            scanf("%s",&g[i]);
            rep(j,0,m) if(g[i][j] == '@') {
                s = Node(i,j,0,0);
                g[i][j]='.';
            }
        }
        vis[s.x][s.y][s.key]=1;
        q.push(s);
        printf("%d\n",bfs());
    }
}

 

 

2018-03-26

 

posted @ 2018-03-25 11:50  悠悠呦~  阅读(182)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end