HDU5094->BFS&&状态压缩
2016-08-17 15:40
453 查看
HDU5094->BFS&&状态压缩
题意:有一个迷宫,每个格子有四个方向,但这四个方向可能是门,可能是墙,也可能是通路,有些格子里有钥匙,每种钥匙只能开对应品种的门,求从(1,1)到(n,m)所花费的最少时间
题解:
相比最基本的迷宫,这个题多了许多状态,因此我们在记录迷宫信息时不能再简单的只记录一张图,而是要记录每个格子的四个方向的状态以及每个格子有没有钥匙,有哪些钥匙。
在记录钥匙的时候,由于钥匙最多有10把,所以可以用10位的二进制来保存状态,如果有编号为i的钥匙,就把这个二进制数的第i位更新成1。
在BFS的过程中,要开标记数组记录获取当前钥匙的状态是否访问过某个节点,防止重复访问。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> using namespace std; int dir[4][2] = {{-1 , 0} , {1 , 0} , {0 , 1} , {0 , -1}}; int Map[55][55][5] ;//前四维存储四个方向是门还是墙,最后一维存储这个格子有没有钥匙 bool flag[55][55][1050] ;//表示当前获得钥匙的状态,防止在同一状态下重复访问 int n , m , p; struct node { int x , y , step , key ; }; int BFS() { bool f = false ; int ans = -1 ; queue<node> q ; node now ; now.x = 1 ; now.y = 1 ; now.step = 0 ; now.key = Map[1][1][4] ; flag[1][1][now.key] = true ; q.push(now) ; while(!q.empty()) { now = q.front() ; q.pop() ; for(int i = 0 ; i < 4 ; i ++) { //如果一个方向不是墙,并且符合是通路或者有对应的钥匙,则可以继续往这个方向走下去 if(Map[now.x][now.y][i] != -1&&(Map[now.x][now.y][i]==0||(Map[now.x][now.y][i]&now.key)>0)) { int xx = now.x+dir[i][0] , yy = now.y+dir[i][1] ; int key = now.key | Map[xx][yy][4] ; if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!flag[xx][yy][key]) { node next ; next.x = xx ; next.y = yy ; next.key = key ; next.step = now.step + 1; flag[xx][yy][key] = true ; if(xx==n&&yy == m) { f = true ; ans = next.step ; break ; } q.push(next) ; } } } if(f) break ; } return ans ; } int main() { while(scanf("%d%d%d" , &n , &m , &p) != EOF) { memset(Map , 0 , sizeof(Map)) ; memset(flag , false , sizeof(flag)) ; int k ; scanf("%d" , &k) ; for(int i = 1 ; i <= k ; i ++) { int x1 , x2 , y1 , y2 , t ; scanf("%d%d%d%d%d" , &x1 , &y1 , &x2 , &y2 , &t) ; for(int j = 0 ; j < 4 ; j ++) { if(x2 - x1 ==dir[j][0] && y2 - y1 == dir[j][1]) { if(t == 0) Map[x1][y1][j] = -1 ; else Map[x1][y1][j] = (1 << (t - 1)) ; } else if(x1-x2 == dir[j][0] && y1-y2 == dir[j][1]) { if(t == 0) Map[x2][y2][j] = -1 ; else Map[x2][y2][j] = (1 << (t-1)) ; } } } scanf("%d" , &k) ; for(int i = 1 ; i<= k ; i ++) { int x , y , z ; scanf("%d%d%d" , &x , &y , &z) ; Map[x][y][4] |= (1 << (z - 1)) ; } if(n == 1 && m == 1) { printf("0\n") ; continue ; } printf("%d\n",BFS()) ; } return 0; }
相关文章推荐
- hdu5094(BFS&状态压缩)
- hdu5094 状态压缩+bfs
- HDU1429胜利大逃亡(续)&&HDU 1885 Key Task BFS+状态压缩+水
- HDU 1429--胜利大逃亡(续)【BFS && 状态压缩】
- hdu5094(bfs,状态压缩)
- hdu2209 翻纸牌游戏--BFS & 位运算 & 状态压缩(待解决)
- HDU 5094 --Maze【BFS && 状态压缩】
- Sicily 1150 简单魔板 && 1151 魔板 (BFS深度优先搜索+康托展开状态压缩)
- hdu 4771 状态压缩+bfs Stealing Harry Potter's Precious
- hdu4771,Stealing Harry Potter's Precious,bfs,状态压缩
- HDU 1429--胜利大逃亡(续)【BFS && 状态压缩】
- DP【状态压缩 】 <简单?> hlg 1473
- HDU1429胜利大逃亡(续)&&HDU 1885 Key Task BFS+状态压缩+水
- HDU 5094 --Maze【BFS && 状态压缩】
- UVa 816 Abbott's Revenge(状态压缩BFS)
- HOJ 2226&POJ2688 Cleaning Robot(BFS+TSP(状态压缩DP))
- hdoj 1429 胜利大逃亡(续)< BFS + 状态压缩>
- Cisco 4506 启动就进入Rommon> 状态
- Paint on a Wall----HDU_4012----BFS_状态压缩
- HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..