文章
14
粉丝
132
获赞
7
访问
33.5k
分析:
这个题目特别之处在于还有锁住的门和钥匙,
要经过这张门,得先拿到这张门的钥匙
对于a-j 10把钥匙,我们共有1024种可能
因此,我们可以采用二进制来记录钥匙的集合
//返回新的钥匙集合
//参数:原始的钥匙集合 获得的钥匙的编号
inline int get_key(int key,int num) {
return key | (1 << num);
}
//返回是否存在门的钥匙
//参数:钥匙集合 门的编号
inline bool has_key(int key,int num) {
return (key & (1 << num)) > 0;
}
所以一共有3层: dis[max_v][max_v][1024]
有这么多种状态,仔细想想就是站在不同的点拥有不同钥匙集合的状态
注意遇到小写字母的时候记得进行左移 再与前一个状态值进行或运算,例如,假设已经用了A 门的要是,状态此时因该是0000000001,意思是拥有了a,如果下一次遇到了J门的钥
匙,也就是j,那就应该是(1<<10) | (0000000001),那么此时的状态应该是1000000001,当遇到已经拥有钥匙的门的时候再进行右移运算,例如下一次遇到J门时,我们应该先将
1000000001右移10位再与 1进行(&)与运算,如果拥有J门的钥匙 应该是1&1=1 ,是真值,可以通过,如果没有,则0&1=0,是假值,则无法通过。
其余的跟普通的bfs都是一样的
需要注意的地方:
1.越界直接返回
2.遇到了某个钥匙,要生成新的钥匙集合
3.遇到了门,要检查当前钥匙集合能不能打开次门,不能打开就往另外一个方向搜
4.门能打开的话且这种状态没有搜过的话,步数加一
5.如果满足了上面条件,但是超时了,也要重新搜
还有一共很重要的一点
就是搜到了终点的时候,这个返回某值然后结束函数的代码的位置
具体请参考代码
#include<bits/stdc++.h>
using namespace std;
#define max...
登录后发布评论
暂无评论,来抢沙发