E. 2.新飞行棋

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

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

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

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

Input
6 6 4
1 2 2 3 1 2
Output
1
Hint
对于前10%的数据,s=t;
对于前40%的数据,n≤200;
对于另外10%的数据,s无法到达t;
对于100%的数据,n≤200000;

# include<iostream>
# include<queue>

using namespace std;
const int MAX=2e5+5;
struct node{
	int dis;
	int num;
};
queue<node>q;
int n,s,t;
int a[MAX],vis[MAX];

inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(!isdigit(ch))  {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch))   {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

void bfs(){
	 while(!q.empty()){
	 	 node p=q.front();
	 	
	 	 if(p.dis == t) {
	 	 	             cout<< p.num ;
	 	 	             return ;
		                }
	     int dis1=p.dis+a[p.dis];
	     
		 if(dis1<=n&&!vis[dis1]){
		 	 q.push({dis1,p.num+1});
		 	 vis[dis1]=1;
		 }
		 
		 int dis2=p.dis-a[p.dis];
		 
		 if(dis2>=1&&!vis[dis2]){
		 	 q.push({dis2,p.num+1});
		 	 vis[dis2]=1;
		 }
		 q.pop();
	 }
	 cout<<-1;
	 return ;
}

int main(){
	n=read();s=read();t=read();
	for(int i=1;i<=n;++i)
	 a[i]=read();
	 if(n==t) {
	 	cout<<0;
	 	return 0;
	 }
	 q.push({s,0});
	 vis[s]=1;
	bfs();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值