J

计院有一个bug电梯,可能是hyk造的,很多bug,电梯只有两个按钮,“上”和“下”,电梯每层都可以停,每层都有一个数字Ki(0<=Ki<=n),当你在一层楼,你按“上”键会到1+K1层,你按“下”键会到1-K1层。当然,电梯不能升到N以上,也不能降到1以下。例如,有一个五层楼的建筑,k1=3,k2=3,k3=1,k4=2,k5=5。从第一层开始,你可以按“上”按钮,然后你就上到第四层,如果在第一层按“下”按钮,电梯就不能做到,因为你知道它不能下到负二层。负二楼不存在。
那么,你想从A层到B层,你至少要按多少次“上”或“下”按钮呢?Input输入由几个测试用例组成,每个测试用例包含两行。 
第一行包含三个整数n,a,b(1<=n,a,b<=200),如上文所述,第二行包含n个整数k1,k2,….kn。 
单个0表示输入的结束。Output对于每种情况下的输入输出一个整数,当你在A层,你必须按下按钮的最少次数,你想去B层。如果你不能到达B层,打印“-1”。Sample Input

5 1 5
3 3 1 2 5
0

Sample Output

3

题目大意就是当以在第i层的时候,按上去i+ki层,,按下去i-ki,问 当你在第A层的时候想要去第B层 至少需要按几次;
经典BFS。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,a,b;
int arr[200+10];
int mark[200+10];
int step[200+10];
int d[2]={1,-1};
int flag=0;
int ans;
void bfs(int x){
    queue<int >que;
    que.push(x);
    mark[x]=1;
    step[x]=0;
    while(que.size()){
        int y=que.front();
        que.pop();
        
        if(y==b){
            ans=step[y];
            flag=1;
            break;
        }
        for(int i=0;i<2;i++){
            int dy=y+arr[y]*d[i];
            if(dy>0&&dy<=n&&mark[dy]==0){
                mark[dy]=1;
                step[dy]=step[y]+1;
                que.push(dy);
            }
        }
        
    }
}
int main(){    
    while(scanf("%d",&n)&&n){
        scanf("%d%d",&a,&b);//从a到b ,,开始时应该在a层 
        for(int i=1;i<=n;i++)
            scanf("%d",&arr[i]); 
        memset(mark,0,sizeof(mark));
        flag=0;
        bfs(a); 
        if(flag) printf("%d
",ans);
        else puts("-1");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/11251708.html