C++ 广搜

发布于:2022-12-29 ⋅ 阅读:(671) ⋅ 点赞:(0)

目录

 奇怪的电梯

输入样例

普通查找与递推

队列优化

抓住那头牛

变形 


 

 奇怪的电梯

电梯只有四个按钮:开,关,上,下,而且第i层楼(1<=i<=N)上有一个数字KiKi(0<=KiKi<=N),上下的层数等于该数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了KiKi(K1K1=3,K2K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?

输入样例

N=5 A=1 B=5
3 3 1 2 5

普通查找与递推

第一步:递推赋初值

方法1:起点(A楼)次数为0,其他未知、未推的是无穷大

方法2(推荐):起点(A楼)次数为1,其他为0表示未知,最终输出结果再减1。

第二步:查找与递推

查找次数为1的楼层,推出这些楼层往上和往下的楼层次数为2;

查找次数为2的楼层,推出这些楼层往上和往下的楼层次数为3;

……

注意:推过的不再推,楼层不合法不推。

队列优化

递推是有顺序的,次数少的推出次数大的,递推过程本身也是有序的的——次数从小到大。我们可以一边递推一边入队,这样先进先出就不需要查找了。最终所有楼层都推出次数,没有入队,也就没有出队,程序结束了。

队列记录的是楼层号x,次数是f[x]。

楼层x 1   2   3   4   5
步数f 1   3   -   2   4
队列x 1   4   2   5 
f[a] = 1, q[1] = a;//入队赋初值,队头队尾是i和j
for(i=j=1; i<=j; i++){
    x = q[i];//出队
    y = xia(x);//递推下一层楼
    if(f[y] == 0){//未推出
        f[y] = f[x] + 1;//递推:次数多1
        q[++j] = y;//入队
    }
}

抓住那头牛

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:

1、从X移动到X-1或X+1,每次移动花费一分钟
2、从X移动到2*X,每次移动花费一分钟

 

假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

问题分析:与电梯相比,只是递推关系由两个方向变成了三个方向而已。

 广度优先搜索,就是按照步数从小到大“递推”,每个格子只推1次,使用队列依次将从小到大推出来的格子入队,不需要查找,时间复杂度就是格子数量。

变形 

1、递推关系:每一项前后之间一般都是相差1步,但项与项之间可能是相邻的上下左右,也可能是几个格子,甚至是比较奇怪的规则。

2、维度变化:有一维数组的、二维数组的、三位数组的……

3、字符串:读入的是字符,需要自己转换成整数模型

4、重复判断:由于步数是1,递推过不需要再推,需要判断重复(推过没有)

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到