新飞行棋(上楼梯)

期末考试终于结束了。Andy同学感觉松了一口气,他决定重温小时候的快乐时光--下飞行棋。但是他弄丢了传统飞行棋需要的骰子,因此他发明了一种新型的飞行棋游戏,规则如下:棋盘上有n个格子,由近到远分别编号为1到n。对于1in,第ii个格子上写着一个正整数N。当玩家处于第a个格子时,他可以选择往后走Na步,或者往前倒退Na步。当然如果Na+a>n,那么他就只能选择后退;同理如果aNa<1,那么他就只能选择前进。保证不会出现既不能前进又不能后退的格子。

Andy学完编程后对一个问题很感兴趣:从编号s出发,至少需要经过几把,可以到达t点?(例如在aa点选择往前走Na步,称之为一把)。

Input

第一行三个整数,分别为n,s,t意义如题面所述。
第二行nn个正整数,第ii个数为Ni

Output

一个数,为最少经过的把数。如果s无法到达t,输出-1。

Samples

Input Copy
6 6 4
1 2 2 3 1 2
Output
1

Hint

  • 对于前10%的数据,s=t
  • 对于前40%的数据,n200
  • 对于另外10%的数据,s无法到达t
  • 对于100%的数据,n200000 

Source

石光中学 FCS2018基础班day 6

这个题怎么说呢,还是看看代码把

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include <math.h>
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=3e5+100;
int n,en,be;
int a[maxn];
int ej[maxn];//摁键数 
void inint(){
    cin>>n>>be>>en;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ej[i]=-1; 
    }
    ej[be]=0;
}
int main(){
    inint();
    int p=0;
    int flag=1;
    while(ej[en]==-1&&flag){
        flag=0;
        for(int i=1;i<=n;i++){//每一次找可以转移的状态 
            if(ej[i]==p){//如第一次找p=0,第二次找p=1的 
                int j=i+a[i];//如果flag=0说明不能到输出-1 
                if(j<=n&&ej[j]==-1){
                    ej[j]=p+1;
                    flag=1;
                }
                j=i-a[i];
                if(j>0&&ej[j]==-1){
                    ej[j]=p+1;
                    flag=1;
                }
            }
        }
        p++;
    }
    printf("%d",ej[en]);
}

和dfs和bfs中的上电梯时一样的题

原文地址:https://www.cnblogs.com/lipu123/p/14364883.html