首页 > 其他分享 >洛谷 奇怪的电梯

洛谷 奇怪的电梯

时间:2024-12-01 12:22:00浏览次数:6  
标签:洛谷 evlt int st 电梯 楼层 搜索 奇怪

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. 优化搜索效率
    标记已访问过的楼层可以帮助减少不必要的搜索分支。因为在寻找从起始楼层到目标楼层的最少操作次数的过程中,重复访问已经走过的楼层通常不会带来更优的解(除非存在特殊的楼层状态变化情况,但在当前代码设定下一般不会)。
    所以,通过及时排除这些已经访问过的楼层,能够缩小搜索空间,让搜索算法更快地聚焦在那些还未被探索过的、可能存在更优解的路径上,从而提高了搜索效率,使得代码能够更快速地找到从起始楼层到目标楼层的最少操作次数(如果存在的话)。

标签:洛谷,evlt,int,st,电梯,楼层,搜索,奇怪
From: https://www.cnblogs.com/xuzhenxuexi/p/18579665

相关文章

  • 洛谷 P1605 迷宫 C语言 bfs
    题目:https://www.luogu.com.cn/problem/P1605题目描述给定一个 N×M方格的迷宫,迷宫里有 TT 处障碍,障碍处不可通过。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到......
  • C语言 神奇的幻方(洛谷 p2615 )幻方是一种很神奇的N*N矩阵
            题目:神奇的幻方(洛谷p2615)幻方是一种很神奇的N*N矩阵:它由数字1,2,3,…,N*N构成,且每行、每列及两条对角线上的数字之和都相等。当N为奇数时,可以通过以下方法构建一个幻方:首先将1写在第一行的中间;之后,按如下方式从小到大依次填写每个数k(k=2,3,…,N*N)若(k-1)在第一......
  • 【洛谷】P2089 烤鸡
    #include<iostream>usingnamespacestd;intmain(){ intn,a,b,c,d,e,f,g,h,i,j,num=0; cin>>n; for(a=1;a<=3;a++) { for(b=1;b<=3;b++) { for(c=1;c<=3;c++) { for(d=1;d<=3;d++) { for(e=1;e<=3;e++) { ......
  • 洛谷 P1680 奇怪的分组(组合数学)
    题目传送门https://www.luogu.com.cn/problem/P1680解题思路这是一道组合数学题。既然题目说了第  个组要大于  个人,那我们不妨先给每个组分  个人。但题目说了是大于  个人,我们只给每个组分了  个人,所以还得分几个人。那么问题就变成了:对于剩下的  个人,我们......
  • P1135 奇怪的电梯 JAVA题解
    题目描述呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 ii 层楼(1≤i≤N1≤i≤N)上有一个数字 KiKi​(0≤Ki≤N0≤Ki​≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例......
  • 洛谷 P2895 [USACO08FEB] Meteor Shower S C语言 bfs
    题目:https://www.luogu.com.cn/problem/P2895题目描述贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。如果将牧场放入一个直角坐标系中,贝茜现在的位置是原......
  • 洛谷 P1162 填涂颜色 C语言 bfs
    题目:https://www.luogu.com.cn/problem/P1162由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 22。例如:6×6的方阵(n=6),涂色前和涂色后的方阵如下:如果从某个 0 出发,只向上下左右 4 个方向移动且仅经过其他 00 的情......
  • 洛谷 P1332 血色先锋队 C语言 bfs
    题目:https://www.luogu.com.cn/problem/P1332#submit题目背景巫妖王的天灾军团终于卷土重来,血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团,以及一切沾有亡灵气息的生物。孤立于联盟和部落的血色先锋军很快就遭到了天灾军团的重重包围,现在他们将主力只好聚集了起来,以......
  • 洛谷 【LGR-206-Div.3】洛谷基础赛 #17 & Diligent-OI Round 1 的 第二题 P11272「Dil
    1.首先,这道题涉及到了区间和和区间积,所以需要用到前缀和s[N]。2.然后,题目解释需要分类讨论!!!下文中的n为n=r-l+1;!!!并非题干中的n;当k >= n时,区间积+k>=k,即使区间全部为1,区间和也是n。(但是如果全为1 区间积+k就为k+1 不合题意),所以种情况为无解,输......
  • 洛谷题单指南-线段树-P3373 【模板】线段树 2
    原题链接:https://www.luogu.com.cn/problem/P3373题意解读:对于序列a[n],支持三种操作:1.对区间每个数乘上一个数2.对区间每个数加上一个数3.求区间和解题思路:由于支持乘、加两种区间修改操作,是线段树的另一种典型应用:多个懒标记显然,这里需要两个懒标记,mul表示对子节点区间每个......