HDU 1429 胜利大逃亡(续) (bfs+状态压缩)

胜利大逃亡(续)

题目连接:

http://acm.hust.edu.cn/vjudge/contest/71151#problem/Dnode

Description


Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
此次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。通过若干次的尝试,Ignatius已画出整个地牢的地图。如今请你帮他计算可否再次成功逃亡。只要在魔王下次视察以前走到出口就算离开地牢,若是魔王回来的时候恰好走到出口或还未到出口都算逃亡失败。
ios

Input


每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t > 0)。接下来的n行m列为地牢的地图,其中包括:
测试

. 表明路 
* 表明墙 
@ 表明Ignatius的起始位置 
^ 表明地牢的出口 
A-J 表明带锁的门,对应的钥匙分别为a-j 
a-j 表明钥匙,对应的门分别为A-J

每组测试数据之间有一个空行。
spa

Output


针对每组测试数据,若是能够成功逃亡,请输出须要多少分钟才能离开,若是不能则输出-1。
code

Sample Input

4 5 17
@A.B.
a*.*.
*..*^
c..b*

4 5 16
@A.B.
a*.*.
*..*^
c..b*

Sample Output

16
-1


题意:


在n*m的地图上,有10种类型的门及其对应钥匙,求最少的时间从起点到达终点,T-1内不能到达则输出-1.
ip


题解:


相似魔塔的搜索题,这里用bfs来搜最小步数便可. 用状态压缩处理每一个位置拿到的钥匙状态.
判重:除了点坐标外,须要额外记录达到当前点的钥匙状态. (由于有些位置可能重复到达).
input


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <list>
#define LL long long
#define eps 1e-8
#define maxn 25
#define mod 100000007
#define inf 0x3f3f3f3f
#define mid(a,b) ((a+b)>>1)
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n, m, T;
char mp[maxn][maxn];
bool vis[maxn][maxn][1<<10];

bool is_ok(int x, int y) {
    return x>=0 && y>=0 && x<n && y<m;
}

struct node {
    int x,y;
    int step, key;
};
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};

int bfs(int sx, int sy) {
    queue<node> q;
    while(!q.empty()) q.pop();
    node cur, next;
    cur.x = sx, cur.y = sy, cur.step = 0, cur.key = 0;
    q.push(cur);
    vis[sx][sy][0] = 1;

    while(!q.empty()) {
        cur = q.front(); q.pop();

        for(int i=0; i<4; i++) {
            int xx = cur.x + dir[i][0];
            int yy = cur.y + dir[i][1];
            if(!is_ok(xx,yy) || mp[xx][yy]=='*') continue;
            next.x = xx, next.y = yy, next.step = cur.step + 1; next.key = cur.key;

            if(next.step == T) continue;
            if(mp[xx][yy] == '^') return next.step;

            if(mp[xx][yy]>='a' && mp[xx][yy]<='z') {
                next.key |= (1 << (mp[xx][yy]-'a'));
            }

            if(mp[xx][yy]>='A' && mp[xx][yy]<='Z') {
                if((next.key & (1 << (mp[xx][yy]-'A'))) == 0)
                    continue;
            }

            if(vis[next.x][next.y][next.key]) continue;
            vis[next.x][next.y][next.key] = 1;
            q.push(next);
        }
    }

    return -1;
}

int main(int argc, char const *argv[])
{
    //IN;

    while(scanf("%d %d %d", &n,&m,&T) != EOF)
    {
        for(int i=0; i<n; i++)
            scanf("%s", mp[i]);

        int sx = -1, sy = -1;
        for(int i=0; i<n; i++) {
            for(int j=0; j<m; j++) if(mp[i][j] == '@') {
                sx = i, sy = j; break;
            }
            if(sx != -1) break;
        }

        memset(vis, 0, sizeof(vis));
        int ans = bfs(sx, sy);

        printf("%d\n", ans);
    }

    return 0;
}
相关文章
相关标签/搜索