洛谷 奇怪的电梯

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

2.输入格式
共二行。

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

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

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

4.输入输出样例

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

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

思路:
模拟在一栋有 n 层楼的建筑中,从起始楼层 A 通过按电梯按钮(电梯每次移动的楼层数由数组 evlt 表示)到达目标楼层 B 的最少操作次数(按电梯按钮的次数)。如果无法到达目标楼层,则输出 -1。

代码示例:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10010;
int n, A, B;
int res = 1e9;//存方案数
int evlt[N];//存按电梯按钮后电梯上升或下降的楼层数
bool st[N];//存每层楼走没走过 为什么要这一步后面说明
//当前在x楼,按了cnt次电梯
void dfs(int x,int cnt)
{
	if (cnt >= res) return;
	if (x<0 || x>n) return;
	if (x == B)
	{
		res = min(res, cnt);
		return;
	}
	//上
	if (x + evlt[x]<= n&& !st[x + evlt[x]]) 
    {
	st[x + evlt[x]] = true;
	dfs(x + evlt[x],cnt+1);
	st[x + evlt[x]] = false;//回溯
	}
	//下
	if (x - evlt[x] > 0&&! st[x - evlt[x]])
	{
		st[x - evlt[x]] = true;
		dfs(x - evlt[x],cnt+1);
		st[x - evlt[x]] = false;//回溯
	}
}
int main()
{
	scanf_s("%d %d %d", &n, &A, &B);
	for (int i = 1; i <= n; i++)
	{
		scanf_s("%d", &evlt[i]);
	}
	dfs(A,0);
	if (res == 1e9)
	{
		printf("-1\n");
	}
	else
	printf("%d", res);
	return 0;
}

为什么要用bool st[N];

  1. 避免重复访问
    在深度优先搜索过程中,如果不进行标记,可能会出现重复访问同一楼层的情况。例如,从某一楼层向上移动到达一个新楼层后,后续搜索过程中可能又会从其他路径再次回到这个新楼层,然后继续进行相同的向上或向下移动操作,这样就会陷入无限循环的搜索路径中,导致搜索无法有效进行。
    通过使用 st 数组来标记每层楼是否已走过,当准备访问某一楼层时,先检查该楼层对应的 st 数组元素值。如果值为 true,表示该楼层已经被走过,就不再对其进行进一步的搜索操作(如向上或向下移动电梯并继续递归搜索),从而避免了重复访问同一楼层,保证了搜索过程能够有序、有效地进行下去。
  2. 优化搜索效率
    标记已访问过的楼层可以帮助减少不必要的搜索分支。因为在寻找从起始楼层到目标楼层的最少操作次数的过程中,重复访问已经走过的楼层通常不会带来更优的解(除非存在特殊的楼层状态变化情况,但在当前代码设定下一般不会)。
    所以,通过及时排除这些已经访问过的楼层,能够缩小搜索空间,让搜索算法更快地聚焦在那些还未被探索过的、可能存在更优解的路径上,从而提高了搜索效率,使得代码能够更快速地找到从起始楼层到目标楼层的最少操作次数(如果存在的话)。
posted @   爱学习的小许?  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示