题目链接

864. 获取所有钥匙的最短路径

题意

给定起点,要求在最短步骤内收集完所有钥匙,遇到每把锁之前只有 有对应的钥匙才能够打开

思路

BFS+状态压缩典型题目

先确定起点和总的钥匙数目,其次难点有两处:

  • 如何确定当前路径下已经收集好特定的钥匙
  • 如何确定钥匙已经全部收集完成

第一个问题:可以把每一个节点的状态定义为(x,y,state),其中state为钥匙数目的二进制表示,例如现在收集'b'这把钥匙,那么state更新为2(000010),括号里面为钥匙的二进制数,如果下一轮遇到'B',只需要检查state里面的倒数第二位是否已经更新即可

第二个问题:钥匙全部收集好的话,那么statey应该为(1<<cnt)-1,其中cnt为总的钥匙数量,比如有6把钥匙,全部收集满的状态为2^6-1(111111),括号里面为钥匙的二进制数

class Solution {
public:
//怎么记录更新之后的连续状态呢
//需要学习的是并非整个路径的状态 ,而是需要记录到某个节点的状态[x][y][state] //1. 有时候可能需要走回头路? 那标记的时候除了位置,再把状态也给标记上
//2. 怎么判断钥匙已经全部取完? (1<<max_len-1) 全部标记
struct Node{
int x,y,state;
Node(int x0,int y0,int state0){
x=x0;y=y0;state=state0;
}
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
// unordered_set<Node> st;
int st[31][31][129];
queue<Node> Q; int shortestPathAllKeys(vector<string>& grid) {
memset(st,0,sizeof(st)); if(grid.empty()) return 0;
int n=grid.size();
int m=grid[0].size();//n行m列 int cnt=0,nx=-1,ny=-1;//钥匙数量,初始值的位置
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(grid[i][j]=='@') {nx=i;ny=j;}
else if(grid[i][j]>='a' &&grid[i][j]<='z') cnt++;
}
}
Q.push(Node{nx,ny,0});
st[nx][ny][0]=1; int step=0;//移动次数
while(!Q.empty()){
int len=Q.size();//这一层的节点数
// if(cnt<=0) break;
for(int i=0;i<len;i++){
Node cur=Q.front();
Q.pop();
if(cur.state==(1<<cnt)-1) return step;
for(int k=0;k<4;k++){
int tmpx=cur.x+dx[k];
int tmpy=cur.y+dy[k];
int nState=cur.state; if(tmpx <0 || tmpx >n-1 || tmpy<0 || tmpy>m-1) continue;//0~n-1 这里不是n 而是大于n-1....... if(grid[tmpx][tmpy]=='#') continue;
if(grid[tmpx][tmpy]>='a' && grid[tmpx][tmpy]<='z'){
nState=cur.state|(1<<(grid[tmpx][tmpy]-'a'));
} if(grid[tmpx][tmpy]>='A' && grid[tmpx][tmpy]<='Z'){
// printf("%d %d\n",nState,nState & (1<<(grid[tmpx][tmpy]-'A')));
if((nState & (1<<(grid[tmpx][tmpy]-'A')))==0){
continue;
}
} //表示已经访问过 加上状态
if(!st[tmpx][tmpy][nState]){
st[tmpx][tmpy][nState]=1;
Q.push(Node{tmpx,tmpy,nState});
}
}
}
step++;
}
return -1;
}
};

leetcode 864. 获取所有钥匙的最短路径(BFS,状态压缩)的更多相关文章

  1. HDU1429+bfs+状态压缩

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

  2. BFS+状态压缩 hdu-1885-Key Task

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...

  3. BFS+状态压缩 HDU1429

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

  4. hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  5. ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

    求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...

  6. poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)

    Description Flip game squares. One side of each piece is white and the other one is black and each p ...

  7. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  8. [Swift]LeetCode864. 获取所有钥匙的最短路径 | Shortest Path to Get All Keys

    We are given a 2-dimensional grid. "." is an empty cell, "#" is a wall, "@& ...

  9. HDU1429--胜利大逃亡(续)(BFS+状态压缩)

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

随机推荐

  1. jenkins 配置任务

    新建筑任务 ""imuke 建一个自由风格的 要执行python .py程序,我们需要把.py所在的目录设置进去 如果保存的是在svn,需要把他的地址放进去 如图: 设置自动构建时 ...

  2. IDEA的基本操作——导入导出jar包

    在使用Jmeter工具测试时,有时也需要导出jar包,测试对应功能,或者自己二次开发Jmeter工具,也是需要导出jar包的.既然经常用,所以就总结了下导入导出jar包的方法. 导入jar包 先打开i ...

  3. Spring Data JPA 的 Specifications动态查询

    主要的结构: 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询. ...

  4. Hive中的集合数据类型

    除了使用础的数据类型string等,Hive中的列支持使用struct, map, array集合数据类型. 数据类型 描述 语法示例 STRUCT 和C语言中的struct或者"对象&qu ...

  5. Linux下源码安装方式安装MySQL

    1.下载安装包:https://downloads.mysql.com/archives/community/  2.安装开发工具和安装包 因为要把源码编译成二进制数据,所以必须要有编译器和解释器 g ...

  6. JAR-使用JAVA命令编译打包一个可执行jar包

    一.开发一个演示项目 项目源代码开发 项目名称叫jar-package-example(其实只是一个文件夹, 用以将演示的所有文件夹和文件存放在其中, 没啥其它作用), 为了方便, 后文统一叫jar- ...

  7. Socket.io详解

    socket.io是一个跨浏览器支持WebSocket的实时通讯的JS. http://socket.io/docs/ 由于HTTP是无状态的协议,要实现即时通讯非常困难.因为当对方发送一条消息时,服 ...

  8. JVM 分代GC策略分析

    JVM 分代GC策略分析   我们以Sun HotSpot VM来进行分析,首先应该知道,如果我们没有指定任何GC策略的时候,JVM默认使用的GC策略.Java虚拟机是按照分代的方式来回收垃圾空间,我 ...

  9. .NET C#中处理Url中文编码问题

    近些日子在做一个用C#访问webservise的程序,由于需要传递中文参数去请求网站,所以碰到了中文编码问题.我们知道像百度这种搜索引擎中,当用户输入中文关键字后,它会把中文转码,以确保在Url中不会 ...

  10. Liunx运维(八)-LIunx磁盘与文件系统管理命令

    文档目录: 一.fdisk:磁盘分区工具 二.partprobe:更新内核的硬盘分区表信息 三.tune2fs:调整ext2/ext3/ext4文件系统参数 四.parted:磁盘分区工具 五.mkf ...