目录
题目
思路
Code
题目
题目内容:
已知存在两个任务队列 A、B,队列成员表示单个任务耗时;为了缩短整体运行时间,需要队列 A 和队列 B 中任务的总耗时一致。
初始时队列 A 和队列 B 的任务总耗时不同,要求只进行一次任务交换:从 A 中选择一个任务,从 B 中选择一个任务,两者互换;交换后要求两个队列的任务总耗时相等。
请你找出队列 A 和队列 B 中需要交换的任务位置 [i,j](数组下标从 0 开始),规则说明:
- 单个任务耗时取值 0<T<100。
- 用例保证均有解,且满足条件的下标对 [i,j] 唯一。
- 队列 A 和队列 B 长度为 1∼50。
输入描述:
第一行输入整型数组 A,表示队列 A 中各任务的耗时,元素之间使用英文逗号分隔。
第二行输入整型数组 B,表示队列 B 中各任务的耗时,元素之间使用英文逗号分隔。
输出描述:
输出数组 [i,j],其中 i 是 A 中参与交换任务的原始下标,j 是 B 中参与交换任务的原始下标,下标从 0 开始。
样例1
输入:
1,2,9 1,2,3,4输出:
[1,0]说明:将队列 A 中的 2(下标为 1)和队列 B 中的 1(下标为 0)互换位置,两个任务队列中任务总耗时均为 11,因此返回互换位置下标 [1,0]。
样例2
输入:
1,15,9 2,4,6,8,25输出:
[1,4]说明:将队列 A 中的 15(下标为 1)和队列 B 中的 25(下标为 4)互换位置,两个任务队列中任务总耗时均为 35,因此返回互换位置下标 [1,4]。
思路
整体思路:对交换前后两数组的总和做恒等变形,得出 A[i]-B[j] 必须恰为两队总耗时差的一半,双重循环枚举第一个满足条件的下标对。
1. 设 sumA、sumB 为交换前 A、B 的总耗时。
2. 若交换 A[i] 与 B[j],则:交换后 A 总和 = sumA - A[i] + B[j]交换后 B 总和 = sumB - B[j] + A[i]
3. 令两式相等并化简:sumA - A[i] + B[j] = sumB - B[j] + A[i]=> 2 * (A[i] - B[j]) = sumA - sumB即:A[i] 与 B[j] 的差值必须恰好等于两队总耗时差的一半。
4. 双重循环枚举所有 (i, j) 组合,找到第一个满足2*(A[i]-B[j]) == sumA-sumB 的下标对直接输出。(题目保证解唯一,所以第一个找到的就是答案)小技巧:不先算 (sumA-sumB)/2 再比较,而是用"乘 2"的形式判断,可以完全避免负数整除/奇数差带来的边界问题。
Code
Python
# -*- coding: utf-8 -*- import sys def find_swap(a, b): """ 在队列 a、b 中寻找交换后能使两队列总耗时相等的下标对 (i, j)。 参数: a: 队列 A 的耗时列表 b: 队列 B 的耗时列表 返回: (i, j) 元组,题目保证存在唯一解 """ # 两队列交换前的总耗时 sum_a = sum(a) sum_b = sum(b) # 交换后总和相等 <=> 2*(a[i]-b[j]) == sum_a - sum_b,先算出右端常数 need = sum_a - sum_b # 双重循环枚举 A 中每个任务与 B 中每个任务的所有配对 for i in range(len(a)): for j in range(len(b)): # 满足等价条件即为答案(题目保证唯一,直接返回) if 2 * (a[i] - b[j]) == need: return i, j # 题目保证有解,理论上不会走到这里;返回 (-1,-1) 仅作兜底 return -1, -1 def main(): """主函数:读入两行数组,求解并按格式输出 [i,j]""" # 一次性读入全部标准输入,按空白(空格/换行/\r)切分成 token: # 第 1 个 token 是数组 A(逗号分隔),第 2 个 token 是数组 B(逗号分隔) data = sys.stdin.read().split() a = list(map(int, data[0].split(','))) b = list(map(int, data[1].split(','))) i, j = find_swap(a, b) # 按题目要求格式输出:[i,j](逗号后无空格),print 自带换行 print("[{},{}]".format(i, j)) if __name__ == "__main__": main()JS
function parseLine(line) { // 先 trim 掉首尾空白(含换行、\r),再按逗号切分并逐个转数字 return line .trim() .split(',') .map((s) => parseInt(s.trim(), 10)); } /** * 在队列 a、b 中寻找交换后能使两队列总耗时相等的下标对 [i, j] * 等价条件:2*(a[i]-b[j]) === sumA - sumB(题目保证解唯一) * @param {number[]} a 队列 A * @param {number[]} b 队列 B * @returns {number[]} [i, j] */ function findSwap(a, b) { // 分别累加两队列总耗时 let sumA = 0; let sumB = 0; for (const v of a) sumA += v; for (const v of b) sumB += v; const need = sumA - sumB; // 交换后相等 <=> 2*(a[i]-b[j]) === need // 双重循环枚举 A 中每个任务与 B 中每个任务的所有配对 for (let i = 0; i < a.length; i++) { for (let j = 0; j < b.length; j++) { // 第一个满足条件的配对即答案(题目保证唯一) if (2 * (a[i] - b[j]) === need) { return [i, j]; } } } return [-1, -1]; // 题目保证有解,此分支仅为兜底 } // ---------- 主流程 ---------- const fs = require('fs'); // 从标准输入(fd 0)一次性读入全部内容,按空白(换行/空格/\r)切分成 token const data = fs.readFileSync(0, 'utf8').trim().split(/\s+/); const a = parseLine(data[0]); // 第 1 个 token:数组 A const b = parseLine(data[1]); // 第 2 个 token:数组 B const [i, j] = findSwap(a, b); // 按题目格式输出 [i,j](逗号后无空格,console.log 自带换行) console.log(`[${i},${j}]`);【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java&Go】:Java&Go真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗? 有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。