新飞行棋(上楼梯)
期末考试终于结束了。Andy同学感觉松了一口气,他决定重温小时候的快乐时光--下飞行棋。但是他弄丢了传统飞行棋需要的骰子,因此他发明了一种新型的飞行棋游戏,规则如下:棋盘上有n个格子,由近到远分别编号为1到n。对于1≤i≤n,第ii个格子上写着一个正整数N。当玩家处于第a个格子时,他可以选择往后走Na步,或者往前倒退Na步。当然如果Na+a>n,那么他就只能选择后退;同理如果a−Na<1,那么他就只能选择前进。保证不会出现既不能前进又不能后退的格子。
Andy学完编程后对一个问题很感兴趣:从编号s出发,至少需要经过几把,可以到达t点?(例如在aa点选择往前走Na步,称之为一把)。
Input
第一行三个整数,分别为n,s,t意义如题面所述。
第二行nn个正整数,第ii个数为Ni。
Output
一个数,为最少经过的把数。如果s无法到达t,输出-1。
Samples
Hint
- 对于前10%的数据,s=t
- 对于前40%的数据,n≤200
- 对于另外10%的数据,s无法到达t;
- 对于100%的数据,n≤200000
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中的上电梯时一样的题