题目
有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1≤i≤N)上有一个数字Ki(0≤Ki≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3,3,1,2,5代表了Ki(K1=3,K2=3,……),从1楼开始。在1楼,按“上”可以到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
解析1(广度优先搜索)
#include<iostream>
#include<queue>
using namespace std;
struct node{
int floor,d;//队列中记录的层数和按钮次数
};
queue<node> Q;
int n,a,b;
int k[1000],vis[1000];//每层楼上下可以跳跃几层,以及是否访问过
int main(){
cin>>n>>a>>b;
for(int i=1;i<=n;i++){
cin>>k[i];
}
Q.push((node){a,0});//将初始元素加入队列
vis[a]=1;//记录初始楼层已访问过
node now;
while(!Q.empty()){
now=Q.front();
Q.pop();
if(now.floor==b){
break;
}
for(int sign=-1;sign<=1;sign+=2){
int dist=now.floor+k[now.floor]*sign;//目标楼层,sign为1是上
if(dist>=1&&dist<=n&&vis[dist]==0){
//如果按钮能到达的楼层有效并且未访问过该楼层
Q.push((node){dist,now.d+1});
vis[dist]=1;//该楼层为已访问过
}
}
}
if(now.floor==b){
cout<<now.d<<endl;
}
else{
cout<<-1<<endl;
}
return 0;
}
解析2(深度优先搜索)
#include<bits/stdc++.h>
using namespace std;
int n,a,b,k[201],dis[201];
void dfs(int m,int ans){
dis[m]=ans;
int v=m+k[m];
if(v<=n&&ans+1<dis[v]){
dfs(v,ans+1);
}
v=m-k[m];
if(v>=1&&ans+1<dis[v]){
dfs(v,ans+1);
}
return;
}
int main(){
memset(dis,0x3f,sizeof(dis));
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%d",&k[i]);
}
dfs(a,0);
printf("%d",dis[b]==0x3f3f3f3f?-1:dis[b]);
return 0;
}