hdu 1429 胜利大逃亡(续)

时间:2022-01-13 20:38:05

题目连接

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

胜利大逃亡(续)

Description

Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

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

Input

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

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

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

Output

针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。

Sample Input

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

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

Sample Output

16
-1

状压bfs。。

 #include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
using std::cin;
using std::cout;
using std::endl;
using std::find;
using std::sort;
using std::map;
using std::pair;
using std::queue;
using std::vector;
using std::multimap;
#define pb(e) push_back(e)
#define sz(c) (int)(c).size()
#define mp(a, b) make_pair(a, b)
#define all(c) (c).begin(), (c).end()
#define iter(c) decltype((c).begin())
#define cls(arr,val) memset(arr,val,sizeof(arr))
#define cpresent(c, e) (find(all(c), (e)) != (c).end())
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define tr(c, i) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
const int N = ;
typedef unsigned long long ull;
char G[N][N];
bool vis[N][N][];
int H, W, T, Sx, Sy;
const int dx[] = { , , -, }, dy[] = { -, , , };
struct Node {
int x, y, key, s;
Node() {}
Node(int i, int j, int k, int l) :x(i), y(j), key(k), s(l) {}
};
void bfs() {
cls(vis, false);
queue<Node> q;
q.push(Node(Sx, Sy, , ));
vis[Sx][Sy][] = true;
while (!q.empty()) {
Node t = q.front(); q.pop();
if (G[t.x][t.y] == '^') {
printf("%d\n", t.s < T ? t.s : -);
return;
}
rep(i, ) {
int key = t.key, x = t.x + dx[i], y = t.y + dy[i];
if (x < || x >= H || y < || y >= W) continue;
if (G[x][y] == '*' || vis[x][y][key]) continue;
if (isupper(G[x][y]) && !(key & ( << (G[x][y] - 'A')))) continue;
if (islower(G[x][y])) key |= << (G[x][y] - 'a');
q.push(Node(x, y, key, t.s + ));
vis[x][y][key] = true;
}
}
puts("-1");
}
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w+", stdout);
#endif
while (~scanf("%d %d %d", &H, &W, &T)) {
rep(i, H) {
scanf("%s", G[i]);
rep(j, W) {
if (G[i][j] == '@') Sx = i, Sy = j;
}
}
bfs();
}
return ;
}