当前位置: 首页 > news >正文

《洛谷刷题笔记》day11

题目:P1135 奇怪的电梯

P1135 奇怪的电梯

题目描述

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

输入格式

共二行。

第一行为三个用空格隔开的正整数,表示 N , A , B N, A, B N,A,B 1 ≤ N ≤ 200 1 \le N \le 200 1N200 1 ≤ A , B ≤ N 1 \le A, B \le N 1A,BN)。

第二行为 N N N 个用空格隔开的非负整数,表示 K i K_i Ki

输出格式

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

输入输出样例 #1

输入 #1

5 1 5
3 3 1 2 5

输出 #1

3

说明/提示

对于 100 % 100 \% 100% 的数据, 1 ≤ N ≤ 200 1 \le N \le 200 1N200 1 ≤ A , B ≤ N 1 \le A, B \le N 1A,BN 0 ≤ K i ≤ N 0 \le K_i \le N 0KiN

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


做法1:DFS

#include <bits/stdc++.h>
using namespace std;
int k[301];//楼层的值 
int minstep[301];//每层楼的最小步数 
int ans=-1;//存储结果 
int n,a,b;
void dfs(int x,int step)
{
	if(ans!=-1&&step>=ans) return;//剪枝
	if(x==b)//到达终点 
	{
		if(ans==-1||step<ans)//判断是否有更小的步数 
		{
			ans=step;
		}
		return;
	}
	//记忆化剪枝:如果当前的步数不比之前的步数更优 
	if(step>=minstep[x]) return;
	minstep[x]=step;//更新最小步数 
	int up=x+k[x];//往上 
	if(up<=n) dfs(up,step+1); //判断是否符合条件 
	int down=x-k[x];//往下 
	if(down>=1) dfs(down,step+1); //判断是否符合条件 
}
int main() {
	
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++)
	{
		cin>>k[i];
	}
	fill(minstep, minstep + 201, INT_MAX);//初始化 
	dfs(a,0); //从a开始 
	cout<<(ans!=-1?ans:-1);
    return 0;
}

做法2:BFS

#include <bits/stdc++.h>
using namespace std;
int k[301];
int step[301];
int n,a,b;
int main() {
	
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++)
	{
		cin>>k[i];
	}
	fill(step, step + 201, -1);//初始化 
	step[a]=0;//起点的步数是0 
	queue<int>q;//创建队列 
	q.push(a);//将起点入队 
	while(!q.empty())//bfs 
	{
		int x=q.front();//获取头元素 
		q.pop();//并弹出 
		if(x==b)//如果到达了终点,就输出步数 
		{
			cout<<step[x];
			return 0;
		}
		//上楼 
		int up=x+k[x];
		if(up<=n&&step[up]==-1)//楼层在条件内且未被访问过 
		{
			step[up]=step[x]+1;//步数++ 
			q.push(up);//入队 
		}
		//下楼 
		int down=x-k[x];
		if(down>=1&&step[down]==-1)//楼层在条件内且未被访问过
		{
			step[down]=step[x]+1;//步数++
			q.push(down);//入队 
		} 
	}
	cout<<-1;//队列为空,未找到输出-1 
    return 0;
}

总结

这道题目是一道经典的搜索问题,适合用来练习 ​DFS(深度优先搜索)​ 和 ​BFS(广度优先搜索)​ 的模板


本文章为平时做题笔记,有什么技术性问题都可以在评论区打出来,我都会认真查看并尽力解答大家的疑问。欢迎大佬来提出修改意见,感谢大家的关注和支持!

相关文章:

  • 如何使用AIOps明确Devps的问题归责
  • 【leetcode题解】二分算法
  • Spring6:8 资源操作-Resources
  • 排序算法总结
  • Spring的IOC
  • 回溯算法经典题目
  • 2025年03月18日柯莱特(外包宁德)一面前端面试
  • spring boot 拦截器
  • Spring Boot 集成 Elasticsearch怎样在不启动es的情况下正常启动服务
  • 什么是API❓
  • 语法: erase_program_eeprom(address)
  • NR SRS Configuration
  • C语言基础系列【27】typedef
  • AF3 quat_to_rot函数解读
  • 线性筛和欧拉函数
  • mysql实例2
  • AF3 rot_to_quat函数解读
  • 群体智能优化算法-蚁狮优化算法(Ant Lion Optimizer, ALO,含Matlab源代码)
  • 【愚公系列】《高效使用DeepSeek》024-儿童教育
  • 2025:sql注入详细介绍
  • 外交部介绍中国赞比亚共同举办人工智能能力建设主题活动情况
  • 金融监管总局:正在修订并购贷款管理办法,将进一步释放并购贷款的潜力
  • 无人机穿越大理崇圣寺千年古塔时“炸机”,当地:肇事者已找到,将被追责
  • 体坛联播|米兰逆转热那亚豪取3连胜,阿诺德官宣离开利物浦
  • 习近平给谢依特小学戍边支教西部计划志愿者服务队队员的回信
  • 传奇落幕!波波维奇卸任马刺队主教练,转型全职球队总裁