1118. 【宽度优先搜索BFS】奇怪的电梯

题目描述

大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?

输入

输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的正整数,表示Ki。

输出

输出文件仅一行,即最少按键次数,若无法到达,则输出-1。

样例输入 复制
5 1 5
3 3 1 2 5
 
样例输出 复制
3
 

BFS——广度优先搜索

用一个队列,维护节点和步数。

开始入队 (A,0)(A,0),然后把上、下入队(合法的话),直到第一次出现 B,其实就是不记录 dis 还不排序的 Dijkstra,记得打标记。

正确性:由于边权全部相等(都是 11),不需要用堆来进行排序(Dijkstra),直接用队列即可。

BFS 代码实现:

#include<bits/stdc++.h>
int n,a,b,k[201];
bool f,u[201];//u 是标记
int ri(){
	int x=0;
	char c=getchar(),f=1;
	while(c<'0'||c>'9'){
		if(c=='-')
			f=-f;
		c=getchar();
	}
	while(c<='9'&&c>='0')
		x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x*f;
}
struct node{
	int x,y;
};
std::queue<node>q;
int bfs(){
	q.push(node{a,0});//入队
	u[a]=1;
	while(!q.empty()){
		int x=q.front().x,y=q.front().y;
		q.pop();
		if(x==b)
			return y;//到了 B
		int xn=x+k[x],yn=y+1;
		if(xn<=n&&xn>0&&!u[xn])//上
			q.push(node{xn,yn}),u[xn]=1;
		xn-=2*k[x];
		if(xn<=n&&xn>0&&!u[xn])//下
			q.push(node{xn,yn}),u[xn]=1;
	}
	return-1;
}
int main(){
	n=ri(),a=ri(),b=ri();
	for(int i=1;i<=n;i++)
		k[i]=ri();
	printf("%d",bfs());
	return 0;
}

### 关于洛谷平台上的广度优先搜索BFS)题目与教程 #### 广度优先搜索BFS)简介 广度优先搜索是一种用于图结构的遍历方法,其特点是按照层次顺序访问节点。它通常利用队列数据结构实现,适用于寻找最短路径等问题[^1]。 #### 洛谷平台上与BFS相关的题目推荐 以下是几道经典的基于BFS的题目: 1. **P1135 奇怪电梯** - 这是一道典型的BFS应用题,涉及在一个特殊规则下的楼层移动问题。通过构建状态转移关系并使用BFS进行探索,可以高效解决该问题[^3]。 2. **P1141 宽度优先搜索 bfs** - 此题提供了一个由0和1构成的二维网格迷宫环境,要求计算从特定位置出发能够到达的最大格子数量。此题充分体现了BFS在处理连通性和可达性方面的优势[^4]。 3. **P1984 跳房子** - 本题是一个简单的跳跃游戏模拟,目标是从起点跳至终点,过程中需满足一定的条件限制。采用BFS策略可有效枚举所有可能的状态组合,从而得出最优解方案。 4. **P1768 小鱼吃大鱼** - 在这个游戏中,玩家控制一条小鱼不断吞噬较小的食物以增长体型直至达到最终目标大小。运用BFS可以帮助快速定位最近的有效食物源,进而优化整体决策过程。 #### 学习资源链接 除了实际练习之外,还可以参考一些高质量的学习资料加深理解: - 【普及组】广度优先搜索BFS——到达型搜索问题_C++算法竞赛[^2] 这些材料不仅讲解了基本原理还提供了丰富的实例分析,非常适合初学者入门以及进阶学习者巩固提升技能水平。 ```cpp // 示例代码展示如何初始化一个标准BFS框架 #include <bits/stdc++.h> using namespace std; int main(){ int n, m; cin >> n >> m; // 输入矩阵尺寸 vector<string> grid(n); for(auto &s : grid){ cin >> s; } while(m--){ int i, j; cin >> i >> j; queue<pair<int,int>> q; bool visited[n][n]; memset(visited,false,sizeof(visited)); q.push({i-1,j-1}); visited[i-1][j-1]=true; int count=1; const int dx[]={-1,0,1,0}; const int dy[]={0,-1,0,1}; while(!q.empty()){ auto [x,y]=q.front();q.pop(); for(int k=0;k<4;++k){ int nx=x+dx[k],ny=y+dy[k]; if(nx>=0 && ny>=0 && nx<n && ny<n && !visited[nx][ny]){ if(grid[x][y]!=grid[nx][ny]){ visited[nx][ny]=true; ++count; q.push({nx,ny}); } } } } cout<<count<<"\n"; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值