华为OD机试 - 乱序整数序列两数之和绝对值最小(Python)

给定一个包含正负整数的有序数组,找到两个数,使得它们的和的绝对值最小。如果数组全是非负数,最小和是前两个数;全是负数,最小和是倒数两个数;否则,可能是非负数部分的前两个数、负数部分的最后两个数或正负数相邻的组合。采用二分查找确定第一个非负数的位置。

题目描述

给定一个随机的整数(可能存在正整数和负整数)数组 nums,请你在该数组中找出两个数,其和的绝对值(|nums[x]+nums[y]|)为最小值,并返回这个两个数(按从小到大返回)以及绝对值。

每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

输入描述

一个通过空格分割的有序整数序列字符串,最多1000个整数,且整数数值范围是 [-65535, 65535]。

输出描述

两数之和绝对值最小值

用例

输入 -1 -3 7 5 11 15
输出 -3 5 2
说明 因为 |nums[0] + nums[2]| = |-3 + 5| = 2 最小,所以返回 -3 5 2。

题目解

<think>好的,我需要处理用户关于华为OD中“荒岛逃生游戏”的题目和解题思路的请求。首先,用户的问题中提到了几个引用,我需要仔细查看这些引用内容,确保回答准确。 根据引用[1]、[2]、[3]、[4],题目的大致描述是:荒岛有两个出口,左右各一个,由一座桥连接。逃生者选择方向(正数向右,负数向左),相遇时会PK,体力值大的获胜并继续逃生,同时减少体力值,相同则同归于尽。需要计算最终存活人数。 接下来,我需要整理题目要求。输入是数组,元素是整数绝对值表示体力,符号表示方向。输出是存活人数,异常输入输出-1。例如示例输入5 10 8 -8 -5,输出是2。 然后,解题思路部分。用户需要的是算法思路,可能涉及栈结构。因为向右逃生的人会先进入栈,遇到向左的人时需要比较体力。这里可能需要遍历数组,用栈保存向右的人,遇到向左的人时不断比较栈顶元素,直到栈空或栈顶体力更大。同时处理体力减少的情况,如果栈顶元素体力等于当前向左的体力,两者都消失。否则,胜者体力减少对方的值,并继续留在栈中。最后统计栈中剩余的向右逃生者和未被击败的向左逃生者。 然后,用户需要具体的代码示例。根据引用中的代码语言,用户可能需要Java或Python。例如,引用[3]提到Java示例,但用户问题中的示例代码是Python的快速排序,可能需要选择一种通用语言。这里选择Python,因为它更易读。 编写代码时需要注意输入处理,判断输入是否合法(比如非数字字符)。然后遍历数组,维护栈结构。对于每个元素,如果是正数,向右,压入栈;如果是负数,向左,需要与栈顶元素比较,循环处理直到栈空或无法击败当前元素。同时,处理体力减少的情况,比如栈顶元素体力是否大于等于当前绝对值,若相等则弹出栈顶,否则栈顶体力减去当前绝对值,继续留在栈中。如果栈顶体力小于当前绝对值,则弹出栈顶,当前绝对值减去栈顶体力,继续比较下一个栈顶元素,直到栈空或者当前体力耗尽。 最后,统计栈中剩余的向右逃生者和未被击败的向左逃生者的数量,相加得到结果。 还要考虑边界情况,比如输入为空、非整数等情况返回-1。例如,如果输入中有非数字字符,或者数组为空,直接返回-1。 然后,生成相关问题,参考用户示例中的结构。可能的问题包括如何处理体力相同的情况、栈结构的作用、算法时间复杂度等。 检查是否存在错误,比如代码逻辑是否正确处理了所有情况,比如同归于尽的情况,或者栈顶体力刚好等于当前绝对值的情况。例如,如果当前向左的体力为8,栈顶是8,则两者都消失,栈弹出,且当前向左的不计入结果。如果栈顶是7,当前是8,则栈顶弹出,当前体力变为1,继续与下一个栈顶比较,直到栈空或无法击败。 可能的问题点在于循环处理栈顶元素的条件是否正确,以及体力减少的逻辑是否正确。例如,当向左的人击败栈顶元素时,需要更新当前体力,继续比较下一个栈顶,直到栈空或者当前体力耗尽。 最后,确保回答结构清晰,分步骤解释解题思路,并附上代码示例和相关问题。</think>### 华为OD真题:荒岛逃生游戏 #### 题目描述 荒岛有两个港口(左、右)通过一座桥连接。逃生者的方向由正负号表示(正向右,负向左),绝对值表示体力值。当两人相遇时,体力值大的存活并减少相应体力,若体力相同则同归于尽。求最终逃生人数。若输入异常,返回-1。 **示例输入** `5 10 8 -8 -5` **示例输出** `2` **解释** 第3人(体力8)和第4人(体力-8)同归于尽;第2人(体力10)击败第5人(体力-5),剩余体力5;第1人(体力5)无对手存活。 --- #### 解题思路 1. **栈结构的应用** 使用栈存储向右逃生者(正数)。当遇到向左逃生者(负数)时,依次与栈顶元素PK: - 若栈顶体力 ≥ 当前绝对值:栈顶体力减少当前绝对值;若栈顶体力变为0,弹出栈顶。 - 若栈顶体力 < 当前绝对值:弹出栈顶,当前绝对值减少栈顶体力,继续与下一个栈顶PK。 - 若栈空且当前体力未耗尽,记录向左逃生者数量[^1][^2]。 2. **算法流程** - 输入合法性校验(非数字字符、空输入)。 - 遍历数组,正数压入栈,负数与栈顶元素PK。 - 统计栈中剩余的向右逃生者和未被击败的向左逃生者总数。 --- #### 参考代码(Python) ```python def escape_survivors(arr): stack = [] left_survivors = 0 for num in arr: if num > 0: stack.append(num) else: current = abs(num) while stack and current > 0: top = stack[-1] if top > current: stack[-1] -= current current = 0 elif top == current: stack.pop() current = 0 else: current -= stack.pop() if current > 0: left_survivors += 1 return len(stack) + left_survivors # 输入处理示例 try: input_str = input().strip() if not input_str: print(-1) else: nums = list(map(int, input_str.split())) print(escape_survivors(nums)) except: print(-1) ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码到自然成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值