胜利大逃亡(续)

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. hive中sql解析出对应表和字段的调查

    ---恢复内容开始--- .阿里的druid中的sql parser有各种关系数据库sql的解析,但hive的不支持. druid初期的版本中是包含hive的,将以前版本中的hive dialect对 ...

  2. SLua 中使用 Lua 5.3 的编译工程

    2016-03-05 更新: 之前编译的库,在 Android 下 Lua_Number 和 Lua_Integer 被编译为了32位,导致从 C# 到 Lua 过程中有64位到32位整型转换会出现溢 ...

  3. JavaScript高级程序设计55.pdf

    输入模式 HTML5为文本字段新增了pattern属性,这个属性的值是一个正则表达式,用于匹配文本框中的值 例如,只想在允许在文本字段中输入数值 <input type="text&q ...

  4. pac 文件使用到的javascript函数

    下面是可用于FindProxyForURL()函数体中的条件函数: 基于主机名的函数: isPlainHostName() dnsDomainIs() localHostOrDomainIs() is ...

  5. Netbeans代码配色主题大搜集

    我用netbeans的原因之一就是因为其支持代码配色主题,这是个对于一个代码配色字体控来说是非常重要的一个功能.理所当然的,我也会收集各种配色主题来时常换换口味. 下面就是我目前收集的Netbeans ...

  6. POJ 2955 括号匹配,区间DP

    题意:给你一些括号,问匹配规则成立的括号的个数. 思路:这题lrj的黑书上有,不过他求的是添加最少的括号数,是的这些括号的匹配全部成立. 我想了下,其实这两个问题是一样的,我们可以先求出括号要匹配的最 ...

  7. sql中时间的一些特殊转换

    1.修改时间的秒和微秒 create table a (Dtime datetime);insert into aselect '2013-08-30 17:59:35' union allselec ...

  8. Js- 菜单

    很简单的JS二级菜单显示,收藏 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  9. Zend Framework 2参考Zend\Authentication(数据库表认证)

    + 转载自:Zend Framework 2参考Zend\Authentication(数据库表认证) 介绍 Zend\Authentication\Adapter\DbTable提供对存储在数据库表 ...

  10. [置顶] sql 向另一个表导数据

    1.如果目的表已经存在: 这两个表结构必须一致 insert into table1 select * from tabel2 2.如果目的表不存在: 这个类似与克隆表 select * into t ...