目录
奇怪的电梯
电梯只有四个按钮:开,关,上,下,而且第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,递推过不需要再推,需要判断重复(推过没有)