文章

14

粉丝

132

获赞

7

访问

33.8k

头像
胜利大逃亡(续) 题解:bfs + 状态压缩
P1725 杭州电子科技大学机试题
发布于2023年5月10日 16:20
阅读数 948

分析:

这个题目特别之处在于还有锁住的门和钥匙,

要经过这张门,得先拿到这张门的钥匙

对于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...
登录查看完整内容


登录后发布评论

暂无评论,来抢沙发