华为OD机考双机位C卷 - 乘坐保密电梯 (Java & Python & JS & GO & C++ & C)

乘坐保密电梯

2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷

华为OD机试双机位C卷真题目录点击查看: 【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)

题目描述

有一座保密大楼,你从0楼到达指定楼层m,必须这样的规则乘坐电梯:

给定一个数字序列,每次根据序列中的数字n,上升n层或者下降n层,前后两次的方向必须相反,规定首次的方向向上,自行组织序列的顺序按规定操作到达指定楼层。

求解到达楼层的序列组合,如果不能到达楼层,给出小于该楼层的最近序列组合。

输入描述

第一行:期望的楼层,取值范围[1,50]; 序列总个数,取值范围[1,23]

第二行:序列,每个值取值范围[1,50]

备注

  • 操作电梯时不限定楼层范围。

  • 必须对序列中的每个项进行操作,不能只使用一部分。

输出描述

能够达到楼层或者小于该楼层最近的序列

示例1

输入

5 3
1 2 6

输出

6 2 1

说明

1 2 6,6 2 1均为可行解,按先处理大值的原则结果为6 2 1

解题思路

1. 问题转化

电梯的运动规则是“上升、下降、上升、下降……”,这实际上是将给定的数字序列分成了两个集合:

  • 上升集合 (Up Set, 记为 $U$):用于第 1、3、5... 次操作,对楼层做加法。
  • 下降集合 (Down Set, 记为 $D$):用于第 2、4、6... 次操作,对楼层做减法。

设所有数字的总和为 $S$,则最终到达的楼层 $H$ 可以表示为:
$$ H = \sum U - \sum D $$
代入 $\sum D = S - \sum U$,得到:
$$ H = 2 \sum U - S $$

题目要求 $H \le m$ 且尽可能接近 $m$(即 $H$ 最大),这等价于要求 $\sum U$ 满足:
$$ 2 \sum U - S \le m \implies \sum U \le \frac{S + m}{2} $$

因此,问题转化为:从给定数组中选出一个子集 $U$,使其元素之和尽可能大,但不超过 $\lfloor \frac{S + m}{2} \rfloor$

2. 约束条件确定

  • 子集大小固定:由于序列必须用完且交替操作,集合 $U$ 的元素个数必须是固定的。
    • 如果总个数 $n$ 是偶数,则 $|U| = n/2$。
    • 如果总个数 $n$ 是奇数,则 $|U| = (n+1)/2$(因为第一次必须上升)。
  • 目标:找到满足上述大小要求,且和最大的子集 $U$。

3. 算法选择:深度优先搜索 (DFS)

由于 $n$ 的范围较小($[1, 23]$),可以使用 DFS(回溯法)来搜索所有可能的子集 $U$。

  • 排序优化:先将数组降序排序。在 DFS 过程中,优先尝试选择较大的数,这样可以更快地逼近最大限制和,结合剪枝策略可以显著提高效率。
  • 剪枝策略
    • 如果当前选的个数超过了规定的大小,停止。
    • 如果当前和已经超过了限制值 $\lfloor \frac{S + m}{2} \rfloor$,停止。
    • (进阶)如果当前和加上剩余所有数都不足以超过已知的最优解,停止。

4. 结果构造与字典序优化

当找到一个满足条件的最佳子集 $U$ 后(剩余元素即为集合 $D$),需要构造最终的输出序列。
题目要求“序列组合”且示例暗示了字典序最大(6 2 1 优于 1 2 6)。

  • 贪心策略:为了让序列的字典序最大,我们应该在每一步都尽可能选择当前可用的最大值。
  • 具体操作
    1. 将集合 $U$ 降序排序。
    2. 将集合 $D$ 降序排序。
    3. 交替从 $U$ 和 $D$ 中取出最大的元素放入结果序列(顺序为:$U_1, D_1, U_2, D_2, \dots$)。
posted @ 2026-03-09 22:53  华为od算法大师  阅读(1)  评论(0)    收藏  举报