胜利大逃亡(续)

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

这次魔王汲取了上次的教训,把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把钥匙,那么可以把10钥匙压缩二进制,比如1000就表示身上只要第4把钥匙的状态,110表示带有第2把和第3把钥匙,那么要判断当前的钥匙串有没有能打开当前门钥匙,那么就只要一个&运算就可以,因为11101110&00100000==00100000 这样就说明那一把钥匙在里面,若为0就不在这里面。如果对于当前点是一把钥匙的时候,只要|运算就可以了,11101110 | 00010000 这样就把当前这把钥匙放进了钥匙串里面了
 
代码如下:
 # include<iostream>
# include<cstring>
# include<cstdio>
# include<queue>
using namespace std;
struct node{
int x,y,key;
}; char map[][];
int vis[][][];
int n,m,t;
int dx[]={,,-,};
int dy[]={,,,-}; int bfs(int sx,int sy){
int x,y,key;
memset(vis,,sizeof(vis));
queue<node> q;
node temp;
temp.x = sx; temp.y = sy; temp.key = ;
q.push(temp);
while(!q.empty()){
temp = q.front(); q.pop();
sx = temp.x; sy = temp.y; key = temp.key;
if(vis[sx][sy][key] > t)
return -;
int i;
for(i=;i<;i++){
x = sx+dx[i]; y = sy+dy[i];
if(x< || x>=n ||y< ||y>=m)
continue;
if(map[x][y]== '^')
return vis[sx][sy][key]+;
if(map[x][y]=='*' || vis[x][y][key])
continue;
if(map[x][y]=='.' || map[x][y] == '@'){
vis[x][y][key] = vis[sx][sy][key] + ;
temp.x = x; temp.y = y; temp.key = key;
q.push(temp);
}
if(map[x][y] >='a' && map[x][y]<='j'){
int key1 = (key|(<<(map[x][y]-'a')));
vis[x][y][key1] = vis[sx][sy][key] + ;
temp.x = x; temp.y = y; temp.key = key1;
q.push(temp);
}
if(map[x][y]>='A' && map[x][y]<='J'){
if(key & (<<(map[x][y]-'A'))){
vis[x][y][key] = vis[sx][sy][key] + ;
temp.x = x; temp.y = y; temp.key = key;
q.push(temp);
}
}
}
}
return -;
} int main(){
int sx,sy,i,j;
while(scanf("%d%d%d",&n,&m,&t)!=EOF){
for(i=;i<n;i++){
scanf("%s",map[i]);
for(j=;j<m;j++){
if(map[i][j]=='@')
{ sx=i; sy=j; }
}
}
int ans = bfs(sx,sy);
if(ans<t)
printf("%d\n",ans);
else
printf("-1\n");
}
return ;
}

HDU 1429 胜利大逃亡(续)(DP + 状态压缩)的更多相关文章

  1. hdu - 1429 胜利大逃亡(续) (bfs状态压缩)

    http://acm.hdu.edu.cn/showproblem.php?pid=1429 终于开始能够做状态压缩的题了,虽然这只是状态压缩里面一道很简单的题. 状态压缩就是用二进制的思想来表示状态 ...

  2. hdu 1429 胜利大逃亡(续) (bfs+状态压缩)

    又开始刷题了 题意:略过. 分析:主要是确定状态量,除了坐标(x,y)之外,还有一个key状态,就好比手上拿着一串钥匙.状态可以用位运算来表示:key&(x,y)表示判断有没有这扇门的钥匙,k ...

  3. hdu 1429 胜利大逃亡(续)(bfs+位压缩)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  4. HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...

  5. HDU 1429 胜利大逃亡(续)(bfs+状态压缩,很经典)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)  ...

  6. hdu 1429 胜利大逃亡(续)

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王 ...

  7. hdu.1429.胜利大逃亡(续)(bfs + 0101011110)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. Hdu 1429 胜利大逃亡(续) 分类: Brush Mode 2014-08-07 17:01 92人阅读 评论(0) 收藏

    胜利大逃亡(续) Time Limit : 4000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Subm ...

  9. HDU 1429 胜利大逃亡(续)(bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. [置顶]VC2013的一个bug

    [置顶]VC2013的一个bug 前段时间在尝试使用一个C++的GUI库nana.这个库最大的特点在于使用现代C++风格去编写GUI程序,而不需要使用大量的比较丑陋的代码(如MFC中的各种宏),或者其 ...

  2. 作品第一课----获取批量checkbox选中的值

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. [LeetCode] 42. Trapping Rain Water 解题思路

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  4. Centos6.4 xen编译部署

    ruiy亲测成功,现将步骤总结如下,一步步往下将可 原文链接 http://blog.csdn.net/liyakun1992421/article/details/9071061 xen 与 kvm ...

  5. Redis Desktop Manager桌面管理工具

    Redis Desktop Manager桌面管理工具,方便管理我们放在redis中的各个缓存 及16个数据库 http://redisdesktop.com/download

  6. 动态规划入门——Eddy's research II

    转载请注明出处:http://blog.csdn.net/a1dark 分析:找规律 #include<stdio.h> int main(){ int m,n; while(scanf( ...

  7. [Redux] Normalizing the State Shape

    We will learn how to normalize the state shape to ensure data consistency that is important in real- ...

  8. 使用 JSSE 定制 SSL 连接的属性--转载

    当数据在网络上传播的时候,通过使用 SSL 对其进行加密和保护,JSSE 为 Java 应用程序提供了安全的通信.在本篇有关该技术的高级研究中,Java 中间件开发人员 Ian Parkinson 深 ...

  9. (转载)为啥我们要学习Linux

    学习Linux也有一阵子了,这过程中磕磕撞撞的,遇到了问题,也解决了一些问题,学习的路子是曲折的,想总结点啥的,让刚刚学习Linux的不会望而生畏. 为啥我们要学习Linux 技术的价值不在于这个技术 ...

  10. 高效 jquery 的奥秘

    当你准备使用 jQuery,我强烈建议你遵循下面这些指南: 1. 缓存变量 DOM 遍历是昂贵的,所以尽量将会重用的元素缓存. // 糟糕 h = $('#element').height(); $( ...