胜利大逃亡(续)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3778    Accepted Submission(s): 1236

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

分析:根据提议可知每到一个点[i,j]有两个状态,1是时间,2是钥匙数,而本题判断是否以前到达点{I,j]需要用到状态2,因为同一个点到达的方式可能钥匙数不一样,从而导致后面能走得路不一样,时间就不用标记,用广搜肯定是同样状态里面的最短时间,所以用mark[i][j][key]标记到达i,j钥匙为key的状态

另外可以发现本题钥匙种类最多10个(a~j),则可以用数位表示,即1111111111表示10个钥匙都有,1111111110表示第一个钥匙没有......0000000000表示没有钥匙

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<string>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<map>
  9. #include<iomanip>
  10. #define INF 99999999
  11. using namespace std;
  12.  
  13. const int MAX=20+10;
  14. char Map[MAX][MAX];
  15. int n,m,t;
  16. int mark[MAX][MAX][1<<11];//1<<1表示在i,j点获得x种的钥匙是否已走过
  17. int dir[4][2]={0,1,0,-1,1,0,-1,0};
  18.  
  19. struct Node{
  20. int x,y,time,key;//在x,y点的时间和获得的钥匙
  21. Node(){}
  22. Node(int X,int Y,int Time,int Key):x(X),y(Y),time(Time),key(Key){}
  23. }start;
  24.  
  25. int BFS(int &flag){
  26. mark[start.x][start.y][start.key]=flag;
  27. queue<Node>q;
  28. Node next,oq;
  29. q.push(start);
  30. while(!q.empty()){
  31. oq=q.front();
  32. q.pop();
  33. for(int i=0;i<4;++i){
  34. next=Node(oq.x+dir[i][0],oq.y+dir[i][1],oq.time+1,oq.key);
  35. if(next.x<0 || next.y<0 || next.x>=n || next.y>=m)continue;
  36. if(mark[next.x][next.y][next.key] == flag || Map[next.x][next.y] == '*')continue;
  37. mark[next.x][next.y][next.key]=flag;
  38. if(next.time>=t)return -1;
  39. if(Map[next.x][next.y] == '^')return next.time;
  40. if(Map[next.x][next.y]>='A' && Map[next.x][next.y]<='Z'){
  41. int k=Map[next.x][next.y]-'A';
  42. if(next.key & (1<<k))q.push(next);//表示有这个钥匙A~J分别对应key里的第1~10位
  43. continue;
  44. }
  45. if(Map[next.x][next.y]>='a' && Map[next.x][next.y]<='z'){
  46. int k=Map[next.x][next.y]-'a';
  47. next.key=next.key | (1<<k);
  48. }
  49. q.push(next);
  50. }
  51. }
  52. return -1;
  53. }
  54.  
  55. int main(){
  56. int num=0;
  57. while(cin>>n>>m>>t){
  58. for(int i=0;i<n;++i)cin>>Map[i];
  59. for(int i=0;i<n;++i){
  60. for(int j=0;j<m;++j){
  61. if(Map[i][j] == '@'){start.x=i,start.y=j;start.time=start.key=0;}
  62. }
  63. }
  64. cout<<BFS(++num)<<endl;
  65. }
  66. return 0;
  67. }

hdu1429之BFS的更多相关文章

  1. 胜利大逃亡(续)hdu1429(bfs)

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

  2. 胜利大逃亡 HDU1429 (bfs)

    最后两题算是这个专题最难的两题了 这题关键是标记数组 我一开始设置的是 四维的  第三维是朝向  第四维是钥匙个数 但是 不同的取法钥匙个数可能会重复   如:取ab钥匙和取ac钥匙都是两枚  导致w ...

  3. hdu1429(bfs+状态压缩)

    思路:有十个门,有十把钥匙,每把钥匙对应一个门,相同的门可以有多个.这样,我们就得按照状态来搜索,用0000000001代表第一个门有钥匙了,1000000000代表第十个门钥匙有了.......一次 ...

  4. BFS+状态压缩 HDU1429

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

  5. HDU1429+bfs+状态压缩

    bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...

  6. HDU1429 bfs

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

  7. hdu1429 胜利大逃亡(续) 【BFS】+【状态压缩】

    题目链接:https://vjudge.net/contest/84620#problem/K 题目大意:一个人从起点走到终点,问他是否能够在规定的时间走到,在走向终点的路线上,可能会有一些障碍门,他 ...

  8. BFS+二进制状态压缩 hdu-1429

    好久没写搜索题了,就当练手吧. vis[][][1025]第三个维度用来维护不同key持有状态的访问情况. 对于只有钥匙没有对应门的位置,置为'.',避免不必要的状态分支. // // main.cp ...

  9. HDU1429 胜利大逃亡 状压bfs

    http://acm.hdu.edu.cn/viewcode.php?rid=22225154 因为总共a-j有10种钥匙,所以可以把有没有钥匙的状态压到一个int数里,然后dfs. 昨天状态特别不好 ...

随机推荐

  1. Win8.1OS64位oracle11安装配置及PL/SQL Developer怎样连接64位oracle

    Oracle 为什么选择oracle 1.oracle可以在主流的平台上执行,而相对于sql server仅仅支持windows,而windows在wr手里攥着呢,所以你懂的.在安全性上来讲,非常多地 ...

  2. CAEmitterLayer实现粒子效果

    在iOS 5中,苹果引入了一个新的CALayer子类叫做CAEmitterLayer.CAEmitterLayer是一个高性能的粒子引擎,被用来创建实时例子动画如:烟雾,火,雨等等这些效果. CAEm ...

  3. iOS 蓝牙4.0开发

    背景: 1.iOS的蓝牙不能用来传输文件.2.iOS与iOS设备之间进行数据通信,使用gameKit.framework3.iOS与其他非iOS设备进行数据通信,使用coreBluetooth.fra ...

  4. iptables简述

    一.linux防火墙基础防火墙分为硬件防火墙和软件防火墙. 1.概述linux 防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙.       包过滤机制:ne ...

  5. border和outline区别

    border和outline区别: border支持box-sizing: border-box,当有边距时,是新增了边框后在按照以前的边距处理 outline不支持box-sizing: borde ...

  6. SQL Server 2005无日志文件附加数据库

    公司网站运营两年多了,日志文件超级大,在重装系统的时候,为了省事,就没有备份日志文件,而且是没有分离就把日志文件给删掉了(下次一定要记得先分离再删日志文件).结果造成数据库怎么都附加不上.出现错误. ...

  7. Android-版本与api对应关系图

    Code name Version API level Lollipop 5.1 API level 22 Lollipop 5.0 API level 21 KitKat 4.4 - 4.4.4 A ...

  8. VS 的winform中生成release模式

    我试过,直接在项目的"Properties"中,修改"Build"标签的"Configuration"还不行.因为之前将不常用的工具栏隐藏了 ...

  9. Enumeration

    Interface Enumeration<E> hasMoreElements() boolean hasMoreElements()    仅当此枚举对象包含至少一个以上元素为真:否则 ...

  10. 多维背包 hrbudt 1335 算法与追MM

    hrbust #include<string.h> //多进制储存数,第i位进制维back[i]+1,可以避免重复 #include<stdio.h> using namesp ...