HDOJ 1429 胜利大逃亡(续)(BFS + 状态压缩)
2016-08-07 23:24
309 查看
胜利大逃亡(续)
Problem DescriptionIgnatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……
这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
Input
每组测试数据的第一行有三个整数n,m,t(2<=n,m<=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
解题思路:由于只有10把钥匙,所以可以进行状态压缩,使用三维数组保存状态。这道题有一个和HDOJ1253相同的坑点,就是bfs函数的返回值问题,因为这个WA了几次。。。
补充(位运算实现技巧):
如果要获得第i位的数据,判断((data&(0X1<<i))==0),若真,为0,假,为1;
如果要设置第i位为1,data=(data|(0X1<<i));
如果要设置第i位为0,data=(data&(~(0X1<<i)));
如果要将第i位取反,data=(data^(0X1<<i);
如果要取出一个数的最后一个1(lowbit):(data&(-data)) (这里利用的是负数取反加1实际上改变的是二进制最低位的1这个性质)
代码如下:
#include <algorithm> #include <cctype> #include <climits> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #define EPS 1e-6 #define INF INT_MAX / 10 #define LL long long #define MOD 100000000 #define PI acos(-1.0) struct node { int x; int y; int time; int keys; }; const int maxn = 22; const int maxm = 22; const int maxkey = (1 << 10) + 5; char maze[maxn][maxm]; int dir[4][2] = {{0,1},{-1,0},{0,-1},{1,0}}; int state[maxn][maxm][maxkey]; int sx,sy; int ex,ey; int n,m,t; int bfs() { memset(state,0,sizeof(state)); node p; p.x = sx,p.y = sy,p.time = 0,p.keys = 0; std::queue<node> que; que.push(p); state[p.x][p.y][p.keys] = 1; while(que.size()){ node q; q = que.front(); que.pop(); if(q.x == ex && q.y == ey) return q.time; for(int i = 0;i < 4;i++){ node r; r.x = q.x + dir[i][0]; r.y = q.y + dir[i][1]; r.keys = q.keys; if(0 <= r.x && r.x < n && 0 <= r.y && r.y < m && maze[r.x][r.y] != '*' && !state[r.x][r.y][r.keys] ){ if('A' <= maze[r.x][r.y] && maze[r.x][r.y] <= 'J'){ int door = maze[r.x][r.y] - 'A'; if(r.keys & (1 << door)){ r.time = q.time + 1; que.push(r); state[r.x][r.y][r.keys] = 1; } } else if('a' <= maze[r.x][r.y] && maze[r.x][r.y] <= 'j'){ int key = maze[r.x][r.y] - 'a'; key = 1 << key; if(!state[r.x][r.y][r.keys | key]){ r.keys |= key; r.time = q.time + 1; que.push(r); state[r.x][r.y][r.keys] = 1; } } else{ r.time = q.time + 1; que.push(r); state[r.x][r.y][r.keys] = 1; } } } } return t; } int main() { while(scanf("%d %d %d",&n,&m,&t) != EOF){ for(int i = 0;i < n;i++){ scanf("%s",maze[i]); } for(int i = 0;i < n;i++){ for(int j = 0;j < m;j++){ if(maze[i][j] == '@'){ sx = i; sy = j; } if(maze[i][j] == '^'){ ex = i; ey = j; } } } int ans = bfs(); printf("%d\n",ans < t ? ans : -1); } return 0; }
相关文章推荐
- HDOJ 1429 胜利大逃亡(续) (BFS + 状态压缩)
- hdoj 1429 胜利大逃亡(续) 【BFS + 状态压缩】
- hdoj 1429 胜利大逃亡(续)< BFS + 状态压缩>
- (HDU 1429)胜利大逃亡(续) BFS + 二进制状态压缩
- hdoj 1429 胜利大逃亡(续) 【BFS+状态压缩】
- HDU 1429 胜利大逃亡(续) (BFS + 状态压缩)
- hdu 1429 胜利大逃亡(续) (bfs + 状态压缩)
- hdu 1429 胜利大逃亡(续) (bfs + 状态压缩)
- hdoj 1429 胜利大逃亡(续) 【BFS+状态压缩】
- HDU 1429 胜利大逃亡(续) (bfs+状态压缩)
- HDU 1429 胜利大逃亡(续)(BFS+状态压缩)
- HDU 1429 胜利大逃亡(续)(BFS+状态压缩)
- BFS+状态压缩 hdu-1429 胜利大逃亡(续)
- hdu 1429 胜利大逃亡(续)(状态压缩+bfs)
- hdu 胜利大逃亡(续) bfs+状态压缩 1429 钥匙与门相对应
- hdu 1429 胜利大逃亡(续) bfs+状态压缩
- HDU 1429 胜利大逃亡(续) (bfs+状态压缩)
- HDU 1429 胜利大逃亡(续) 状态压缩BFS
- hdu 1429 胜利大逃亡(续)(bfs+状态压缩)
- HDOJ 4771 Stealing Harry Potter's Precious(bfs + 状态压缩)