目录
题目
思路
Code
题目
题目内容:
嵌入式传感器使用一个 32 位数据包 packet 传递寄存器数据,各字段从低位到高位排列如下:
第 0 位是状态位,1 表示数据正常,0 表示状态异常。
第 1 至 2 位是寄存器 ID。
第 3 位是数据类型,0 表示固定长度,1 表示变长。
第 4 至 11 位是 8 位修正因子。
第 12 至 15 位是有效数据长度 length。
第 16 至 30 位是 15 位数据区。
第 31 位是奇偶校验位。
固定长度数据的 15 位数据区全部有效。变长数据只取数据区最低的 length 位,其他数据位不参与校验和运算。
请按以下顺序解析数据包:
首先检查状态位。状态异常时输出 -1。
然后统计有效数据位和第 31 位校验位中二进制 1 的总数。总数为奇数时校验失败,输出 -2。
接着检查变长数据的长度。数据类型为变长且 length 为 0 时输出 -3。
通过以上检查后,根据寄存器 ID 对有效数据和修正因子执行运算:
寄存器 ID 为 0 时执行按位与。
寄存器 ID 为 1 时执行按位或。
寄存器 ID 为 2 时执行按位异或。
寄存器 ID 为 3 时执行按位同或,即对异或结果逐位取反。
输入描述:
输入一个十进制整数 packet,表示一个 32 位数据包。输入既可能是 32 位有符号整数,也可能是同一位模式对应的非负整数。
输出描述:
若数据包异常,按检查顺序输出 -1、-2 或 -3。
若数据包正常,输出寄存器运算结果对应的 uint32 十进制值。
样例 1
输入:
343873输出:
4说明:
343873 的 32 位表示为 0x00053F41。状态位为 1,寄存器 ID 为 0,数据类型为固定长度,修正因子为 0xF4,实际数据为 0x0005,校验位为 0。
有效数据中有两个二进制 1,偶校验通过。寄存器 ID 为 0,执行 0x0005 与 0x00F4,结果为 4。
样例 2
输入:
0输出:
-1说明:
状态位为 0,直接输出 -1。
思路
整体思路:先把输入归一化为 32 位无符号位模式,再用右移和掩码提取各字段。
第一步:根据数据类型确定有效数据。固定长度保留全部 15 位,变长类型只保留最低 length 位。
第二步:严格按状态、偶校验、变长长度的顺序检查。偶校验只统计有效数据位和第 31 位,不能把寄存器 ID、修正因子等控制字段算进去。
第三步:根据寄存器 ID 执行与、或、异或或同或。同或取反后必须限制为 32 位,避免语言自身的有符号整数或无限位整数影响结果。
边界处理:变长 length 为 0 时仍先完成偶校验;bit31 置位的负数输入保留原始 32 位;正常结果统一按 uint32 十进制输出。
复杂度分析:只处理固定数量的位字段,时间复杂度 O(1),空间复杂度 O(1)。
Code
import sys packet = int(sys.stdin.read().strip()) # 与 0xFFFFFFFF 做与运算只保留低 32 位,因此负数输入也会还原成原始数据包位模式。 value = packet & 0xFFFFFFFF # 每次右移都把目标字段送到最低位,再用掩码清除相邻字段。 status = value & 0x1 register_id = (value >> 1) & 0x3 data_type = (value >> 3) & 0x1 correction = (value >> 4) & 0xFF length = (value >> 12) & 0xF data = (value >> 16) & 0x7FFF parity_bit = (value >> 31) & 0x1 if data_type == 0: # 固定长度类型的 15 位数据区全部参与校验和寄存器运算。 effective_data = data else: # 变长类型只保留数据区最低的 length 位;length 为 0 时掩码自然为 0。 effective_data = data & ((1 << length) - 1) if status == 0: # 状态异常的优先级最高,不再用后续字段覆盖错误码。 print(-1) elif (bin(effective_data).count("1") + parity_bit) % 2 == 1: # 偶校验只计算有效数据位和 bit31,控制字段中的 1 不参与统计。 print(-2) elif data_type == 1 and length == 0: # 题目规定先校验再判断零长度,所以该分支必须放在校验失败之后。 print(-3) else: if register_id == 0: result = effective_data & correction elif register_id == 1: result = effective_data | correction elif register_id == 2: result = effective_data ^ correction else: # Python 的按位取反会保留无限个高位 1,截取低 32 位才是寄存器同或结果。 result = ~(effective_data ^ correction) & 0xFFFFFFFF print(result)JS
const fs = require("fs"); const packet = Number(fs.readFileSync(0, "utf8").trim()); // >>> 0 把输入转换为无符号 32 位位模式,负数也会保留原始低 32 位。 const value = packet >>> 0; // 无符号右移后用掩码取字段,避免 JavaScript 位运算的有符号结果影响高位。 const status = value & 0x1; const registerId = (value >>> 1) & 0x3; const dataType = (value >>> 3) & 0x1; const correction = (value >>> 4) & 0xFF; const length = (value >>> 12) & 0xF; const data = (value >>> 16) & 0x7FFF; const parityBit = value >>> 31; let effectiveData; if (dataType === 0) { // 固定长度类型使用数据区全部 15 位。 effectiveData = data; } else { // 变长类型只保留最低 length 位;length 为 0 时有效数据为 0。 effectiveData = data & ((1 << length) - 1); } if (status === 0) { // 状态异常必须最先返回,不能被后续错误码覆盖。 console.log(-1); } else { let oneCount = parityBit; for (let bits = effectiveData; bits !== 0; bits >>>= 1) { // 逐位统计有效数据,再加上 bit31;寄存器 ID 等控制字段不参与偶校验。 oneCount += bits & 0x1; } if (oneCount % 2 === 1) { console.log(-2); } else if (dataType === 1 && length === 0) { // 变长零长度在校验通过后才返回,保持规定的判断顺序。 console.log(-3); } else { let result; if (registerId === 0) { result = effectiveData & correction; } else if (registerId === 1) { result = effectiveData | correction; } else if (registerId === 2) { result = effectiveData ^ correction; } else { // JavaScript 位运算先产生有符号值,>>> 0 将同或结果还原为 uint32。 result = (~(effectiveData ^ correction)) >>> 0; } console.log(result >>> 0); } }【华为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。让他帮助你查询原因。