P1135 奇怪的电梯 (bfs)

题目背景

感谢 @[yummy](https://www.luogu.com.cn/user/101694) 提供的一些数据。

题目描述

呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 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`。

输入 #1
5 1 5
3 3 1 2 5

输出 #1
3

说明/提示

对于100% 的数据,1≤N≤200,1≤A,B≤N,0≤Ki​≤N。

本题共 16 个测试点,前15个每个测试点 6 分,最后一个测试点 10 分。

//思路//

这一题我用的是广搜(bfs),首先看我们所在的A楼是不是要求的B楼,然后通过while循环来看要坐几回电梯。

//代码//

#include<bits/stdc++.h>        //万能头文件
using namespace std;               
int n,a,b,k[205],ans[205],q[205],f,r,xx[3]={0,-1,1};
//楼层的总数n,最开始所在的楼层a,要去的楼层b,所有的楼层数字k数组,去每一个楼层按键次数ans数组,每一次去的楼层q数组,边界设置条件f和r,移动距离xx数组
bool bb[205];                  //避免一直重复的bb数组
void bfs(int x) {              //bfs函数
	r++;                       //设定右边边界
	q[r]=x;                    //在第r次时走的是x层(其实是上一个走过的楼层)
	bb[x]=1;                   //x层走过了
	ans[x]=0;                  //因为x层就是我们所在的楼层,所以次数是0
	if(x==b) {                 //如果我们所在的楼层就是我们要去的楼层
		cout<<ans[x];          //直接输出ans[x](0)
		return ;               //完毕
	}                          //如果我们所在的楼层不是我们要去的楼层
	while (f!=r) {             //只要左边的边界不是右边的边界
		f++;                   //左边边界向右
		for (int i=1;i<=2;i++){//向下向上走一下
			int nx=q[f]+xx[i]*k[q[f]];
                               //定义现在的位置nx,让它等于它的前一楼层减或加它的楼层数字
			if (nx>=1&&nx<=n&&bb[nx]==0) {
                               //如果nx这一楼层存在,没有到地下或是超出最大楼层,并且没有走过
				r++;           //扩大右边边界
				q[r]=nx;       //将上一个走过的楼层更新成nx
				bb[nx]=1;      //nx楼层走过了
				ans[nx]=ans[q[f]]+1;
                               //到达nx楼层是到它的前一楼层的次数加1
				if(nx==b) {    //如果要到达的楼层就是nx楼层
					cout<<ans[nx];
                               //输出它的次数
					return ;   //完毕
				}                
			}                      
		}                                
	}                                     
	cout<<"-1";                //搜到最后也没到达要到达的楼层,说明到达不了,输出-1     
}
int main(){
	cin>>n>>a>>b;              //输入楼层的总数,最开始所在的楼层,要到达的楼层
	for (int i=1;i<=n;i++) {   //循环输入每一楼层的数字
		cin>>k[i];             //存入k数组里
	}
	bfs(a);                    //开始坐电梯
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值