通过率 47% · 提交 683 · 通过 321
小慕正在参与一个数字比大小的游戏。游戏开始前,小慕和对手各自拿到一个长度相同的,两个序列不完全相同,其中的数字是随机生成的。 小慕和对手各自从自己的数字序列中挑选出一个数字进行大小比较。如果小慕的数字更大,小慕得1分,对手扣1分;如果小慕的数字更小,小慕扣1分,对手得1分;如果数字相等,则双方分数都不变。 每次使用过的数字都会被丢弃。请问小慕最多能赢对手多少分?
这类题属于华为 OD 机考真题方向中「200分 / 双指针」方向的高频题型,通常考察对「200分 / 双指针」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
输入数据的第1个数字表示数字序列的长度N,后面紧跟着两个长度为N的数字序列。
A可能赢B的最大分数
示例 1
输入示例
3 4 8 10 3 6 4
输出示例
3
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
这道题很明显是一道贪心结合双指针的题目。由于平局情况的出现,本题难点在于我们如何地选择策略。
很容易想到我们可以采取类似田忌赛马的策略:为了使得 A 赢的尽可能多,每次出现 A 中元素较小的时候,我们总是选择这个较小的元素和 B 中尽可能大的数去分组。
首先需要将两个数组各自排序,方便考虑两个数组里的最值情况。
我们设置四个指针 ia_left、ia_right、ib_left、ib_right,分别指向 A、B 数组中尚未比较过的元素的最小值和最大值。其初始化为:
如下图所示:
在一个 while 循环中,比较 A 和 B 中尚未比较过元素的最小值,即 A[ia_left] 和 B[ib_left]。
若 A[ia_left] > B[ib_left],由于选择 B 中的其他数字,可能会导致 A[ia_left] 无法获胜,故选择该组进行比较,A 获胜。
若 A[ia_left] < B[ib_left],由于此时 A 中最小值小于 B 中的任意一个元素,我们不妨采取田忌赛马的策略,让 A[ia_left] 和 B[ib_right] 进行分组,B 获胜。
若 A[ia_left] == B[ib_left],这是最复杂的情况。我们继续考虑 A 和 B 中尚未比较过元素的最大值,即 A[ia_right] 和 B[ib_right] 的情况。
若 A[ia_right] > B[ib_right],此时若令 A[ia_left] 和 B[ib_right] 分组,由于 A[ia_right] 无论怎么配对都是必胜,但 A[ia_left] 原本可以平局的配对现在却输了,故不能采取这样的策略。因此让 A[ia_right] 和 B[ib_right] 分组,A 获胜。
若 A[ia_right] < B[ib_right],由于此时 B[ib_right] 大于 A 中的任何一个元素,A 无论如何配对都必输,故仍然维持着田忌赛马的策略,令 A[ia_left] 和 B[ib_right] 分组,B 获胜。
若 A[ia_right] == B[ib_right],此时固然可以令 A[ia_left] 和 B[ib_left]、A[ia_right] 和 B[ib_right] 两两分组,但剩余元素的比较可能会让 A 的失利场次增多。
以上图为例子,如果选择 A 的 1 和 B 的 1 分组,A 的 4 和 B 的 4 分组,那么剩下的 A 的 2 只能和 B 的 3 分组。A 的结果是平 2 负 1,这不是最优解。最优解仍为 A 的 1 和 B 的 4 分组,剩下就存在 A 的 2 和 B 的 1 分组,A 的 4 和 B 的 3 分组。A 的结果是胜 2 负 1,这样才是最优解。
故仍然应该选择 A[ia_left] 和 B[ib_right] 进行分组,此时丢失的分数,可能能够在 A[ia_right] 的其他配对中获取回来。
显然这种情况可以和上一种情况 A[ia_right] < B[ib_right] 合并在一起,即:
本题核心逻辑其实就是田忌赛马,在 A[ia_left] 必定无法胜利的情况下(无论是必输还是可能平局),都尽量地让 A[ia_left] 和 B[ib_right] 配对。
复杂度分析
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有