题目描述
大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?
输入
输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。
输出
输出文件仅一行,即最少按键次数,若无法到达,则输出-1。
样例输入 复制
5 1 5 3 3 1 2 5
样例输出 复制
3
BFS——广度优先搜索
用一个队列,维护节点和步数。
开始入队 (A,0)(A,0),然后把上、下入队(合法的话),直到第一次出现 B,其实就是不记录 dis 还不排序的 Dijkstra,记得打标记。
正确性:由于边权全部相等(都是 11),不需要用堆来进行排序(Dijkstra),直接用队列即可。
BFS 代码实现:
#include<bits/stdc++.h>
int n,a,b,k[201];
bool f,u[201];//u 是标记
int ri(){
int x=0;
char c=getchar(),f=1;
while(c<'0'||c>'9'){
if(c=='-')
f=-f;
c=getchar();
}
while(c<='9'&&c>='0')
x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
struct node{
int x,y;
};
std::queue<node>q;
int bfs(){
q.push(node{a,0});//入队
u[a]=1;
while(!q.empty()){
int x=q.front().x,y=q.front().y;
q.pop();
if(x==b)
return y;//到了 B
int xn=x+k[x],yn=y+1;
if(xn<=n&&xn>0&&!u[xn])//上
q.push(node{xn,yn}),u[xn]=1;
xn-=2*k[x];
if(xn<=n&&xn>0&&!u[xn])//下
q.push(node{xn,yn}),u[xn]=1;
}
return-1;
}
int main(){
n=ri(),a=ri(),b=ri();
for(int i=1;i<=n;i++)
k[i]=ri();
printf("%d",bfs());
return 0;
}