题目连接
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。。
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<vector> 7 #include<queue> 8 #include<map> 9 using std::cin; 10 using std::cout; 11 using std::endl; 12 using std::find; 13 using std::sort; 14 using std::map; 15 using std::pair; 16 using std::queue; 17 using std::vector; 18 using std::multimap; 19 #define pb(e) push_back(e) 20 #define sz(c) (int)(c).size() 21 #define mp(a, b) make_pair(a, b) 22 #define all(c) (c).begin(), (c).end() 23 #define iter(c) decltype((c).begin()) 24 #define cls(arr,val) memset(arr,val,sizeof(arr)) 25 #define cpresent(c, e) (find(all(c), (e)) != (c).end()) 26 #define rep(i, n) for (int i = 0; i < (int)(n); i++) 27 #define tr(c, i) for (iter(c) i = (c).begin(); i != (c).end(); ++i) 28 const int N = 22; 29 typedef unsigned long long ull; 30 char G[N][N]; 31 bool vis[N][N][1030]; 32 int H, W, T, Sx, Sy; 33 const int dx[] = { 0, 0, -1, 1 }, dy[] = { -1, 1, 0, 0 }; 34 struct Node { 35 int x, y, key, s; 36 Node() {} 37 Node(int i, int j, int k, int l) :x(i), y(j), key(k), s(l) {} 38 }; 39 void bfs() { 40 cls(vis, false); 41 queue<Node> q; 42 q.push(Node(Sx, Sy, 0, 0)); 43 vis[Sx][Sy][0] = true; 44 while (!q.empty()) { 45 Node t = q.front(); q.pop(); 46 if (G[t.x][t.y] == '^') { 47 printf("%d ", t.s < T ? t.s : -1); 48 return; 49 } 50 rep(i, 4) { 51 int key = t.key, x = t.x + dx[i], y = t.y + dy[i]; 52 if (x < 0 || x >= H || y < 0 || y >= W) continue; 53 if (G[x][y] == '*' || vis[x][y][key]) continue; 54 if (isupper(G[x][y]) && !(key & (1 << (G[x][y] - 'A')))) continue; 55 if (islower(G[x][y])) key |= 1 << (G[x][y] - 'a'); 56 q.push(Node(x, y, key, t.s + 1)); 57 vis[x][y][key] = true; 58 } 59 } 60 puts("-1"); 61 } 62 int main() { 63 #ifdef LOCAL 64 freopen("in.txt", "r", stdin); 65 freopen("out.txt", "w+", stdout); 66 #endif 67 while (~scanf("%d %d %d", &H, &W, &T)) { 68 rep(i, H) { 69 scanf("%s", G[i]); 70 rep(j, W) { 71 if (G[i][j] == '@') Sx = i, Sy = j; 72 } 73 } 74 bfs(); 75 } 76 return 0; 77 }