简介:这份文档围绕华为OD机考整理出100道高频经典真题,适合已有一定编程基础、正在备考OD机考的开发者。题目涵盖5键键盘的输出、N进制减法、报数游戏等典型场景,每道题均附有Java代码实现与解析,重点考察状态模拟、剪贴板逻辑、不同进制下的字符串减法与边界校验等能力。例如“5键键盘的输出”需维护屏幕、选中区、剪贴板三个状态变量;“N进制减法”则要处理前导零校验、借位以及负数结果,这些正是机考容易失分的环节。资源共1个docx文件,整体包体仅688KB,便于下载保存与随时查阅,目前已有22688人浏览学习,是针对性刷题的实用参考资料。阅读时建议先独立完成题目再对照答案,能更客观评估知识掌握情况,快速熟悉机考题型与考察重点,提升解题速度和通过率。
1. 华为OD机考100题(含答案):这份文档真正能帮你解决什么
华为OD机考100题(含答案)这类文档,在准备投递华为OD岗位的开发者和测试开发候选人中间流传度很高。OD机考一般是限时在线编程考试,常见安排是两个半小时左右、共三道编程题,分数按测试用例通过比例折算,不设现场问答,全部在线上裁判系统里完成。这份100题文档的核心价值,是把高频考点集中到一份清单里,让你不用从零开始在题库里大海捞针。
但这里有个反直觉的结论:看懂100题的答案,和通过机考是两回事。从一线反馈来看,真正导致翻车的往往不是算法难度,而是多行输入解析、隐藏用例边界、考场时间分配这三件事。文档解决的是“考什么”的覆盖问题,“怎么考”要靠模拟练习补上。这篇文章会用一线备考者的常见做法,把这一百题拆成复习地图、刷题计划、考场模板和避坑清单,新手能照着走,熟手也能对照查漏。
2. 华为OD机考到底考什么:从题型分布反推复习重点
2.1 三道题的难度阶梯与判分逻辑
华为OD机考的常见形态是三道题,难度呈阶梯上升。第一题偏简单,通常考察字符串处理、数组模拟、排序、哈希表去重这类基础操作,目标是把大多数考生稳住心态;第二题中等,常出现在DFS/BFS、滑动窗口、贪心、双指针这个区间;第三题是压轴题,多见动态规划、复杂状态搜索、大模拟,用来拉开区分度。三道题的分值权重并不平均,常见权重是前面两道题的权重加总略低于第三题的情况。也就是说,第三题做不出来,不代表一定没机会,只要前两题拿稳,总分依然有机会过线。
判分逻辑是这套机考最容易被低估的地方。每道题会挂若干组测试数据,每一组里有多个测试用例,系统按通过的用例比例折算该题得分。这意味着你不一定需要“全部AC”才能拿分,暴力写法能过掉一部分用例就有部分分。反过来,如果你的代码有一个边界条件漏了,可能只有全量用例里大部分通过,得分卡在70分附近,离满分就差一个判断条件。
所以实际策略应该是:每道题先保证能跑通样例和常规用例,再考虑优化。很多人花四十分钟在第一题上追求完美,结果第三题只有二十分钟,最后总分反而不如“先拿稳一、二题,第三题写暴力拿部分分”的同批考生。我一般建议,拿到题目先看分值分布和数据规模,数据量小时暴力解就有性价比。
2.2 100题里最高频的五个知识块
翻看历年考生回忆题和整理文档,华为OD机考的高频考点非常集中,按出现频次排序大致有五块。
| 知识块 | 典型题面特征 | 上手成本 | 备考优先级 |
|---|---|---|---|
| 字符串与正则 | 日志解析、协议文本提取、敏感词替换 | 低 | 必拿 |
| 数组与双指针 | 合并区间、去重、子数组求和 | 低 | 必拿 |
| 图论DFS/BFS | 连通块数量、岛屿数量、地图最短步数 | 中 | 重点 |
| 动态规划 | 背包、路径计数、递推求最值 | 高 | 按目标分取舍 |
| 栈与优先队列 | 单调栈求下个更大值、堆做TopK | 中 | 重点 |
字符串与数组是最常出现在第一题的考点,很多题就是把一段带格式的输入切分成字段,再做一次排序或统计,整体不涉及复杂算法。DFS/BFS在第二题出现概率极高,尤其是矩阵类题,二维网格上求连通块、最短路径、可达区域这类题面几乎是固定套路。动态规划通常压轴,但考察的方向并不刁钻,多为背包和线性递推,状态定义清楚后实现难度可控。
备考时建议按“字符串数组→图论→动态规划”的顺序推进。原因很简单:字符串题能快速建立信心,也能顺带练熟输入输出;图论题是第二题的主力,值得多花时间;动态规划投入产出比不稳定,如果备考时间只剩三周,可以把常见DP模型过一遍,不必死磕难题。
2.3 华为OD机考和LeetCode的三点本质差异
很多备考者直接用刷题App练习,这没问题,但不能忽略机考与主流刷题平台的三点差异。
第一,输入输出完全裸奔。LeetCode把参数封装成函数,你只管核心逻辑;机考要自己从标准输入里读多行文本、按空格或逗号切分、转成目标类型、再按指定格式打印结果。这一步看似简单,实际操作时却会消耗大量时间。字符读取多了一个空格、行尾换行符没处理干净,都可能让解析错位。
第二,题目文本的边界条件描述往往不够严谨。有的题面只有一段业务场景描述,不会明确告诉你数组长度为零时该返回什么。这时只能靠经验假设“输入长度一定大于0”,或者写空值兜底逻辑。LeetCode的题目描述经过沉淀,边界条件相对规范,而机考题是半业务半算法风格,信息往往藏在样例之外。
第三,判分策略不同。刷题平台只报AC或WA,机考是按用例通过比例算分。这种策略带来的直接后果是“部分分陷阱”——你觉得代码没问题,其实有一个边界漏了,分数不上不下。所以写完代码后,要额外检查空输入、单元素输入、全是相同元素、数据量最大的场景这四类用例。
3. 把100题文档变成刷题计划:从.docx到每日任务的具体做法
3.1 第一步:提取题目文本,按知识点重新分组
拿到一份“100题(含答案).docx”,直接按文档顺序从头刷到尾是错误的做法。这种文档多半是按收录时间排序,而不是按考点排序,顺着刷容易前面全是字符串题、后面全是图论题,越刷越偏。我一般会先把题目文本提取出来,按知识点重新分组,再排进每日计划。
如果你的文档是文字型docx而不是扫描图片,可以用Python脚本快速提取。先用下面的脚本把文档里的题目和答案段落按题号切出来:
import re import docx doc = docx.Document("华为OD机考100题含答案.docx") full_text = [] # 按段落读取,保留结构信息 for para in doc.paragraphs: text = para.text.strip() if text: full_text.append(text) # 用正则切分:假设题号格式为 “题1.”、“题目2” 等 pattern = re.compile(r"^(题\s*\d+[\.、]|题目\s*\d+|#\s*\d+)") blocks = [] current = None for line in full_text: if pattern.match(line): if current is not None: blocks.append(current) current = {"title": line, "content": []} else: if current is not None: current["content"].append(line) if current is not None: blocks.append(current) # 按关键词给题目归类 keywords = { "字符串": ["字符串", "字符", "日志", "解析", "替换"], "图论": ["矩阵", "网格", "岛屿", "连通", "路径", "迷宫"], "动态规划": ["背包", "最大", "最小", "方案数", "递推"], "栈和队列": ["栈", "优先队列", "堆"], "双指针": ["指针", "区间", "合并", "滑动"], } for block in blocks: text = "".join(block["content"]) hit_tags = [tag for tag, words in keywords.items() if any(w in text for w in words)] print(block["title"], "->", ",".join(hit_tags) if hit_tags else "未分类")逻辑说明:脚本用docx库逐段读入文档,剔除空段落后按题号正则切分,再对每道题的内容做关键词匹配。关键词表的思路是“业务词推导算法”,例如题面出现“日志”“替换”就归到字符串类,出现“连通”“迷宫”归到图论。说明一点:这段代码不会自动标出正确答案对应的知识点,只负责帮你快速建立索引,最终归类还是要扫一眼题目确认。
参数说明:pattern里的正则支持“题1.”“题目2”“#3”这几种常见题号格式,如果你的文档用“一、”“二、”做编号,需要把pattern改成^(第?[一二三四五六七八九十百]+[、.])。keywords列表后续可以自己增删,做法是统计归类后空白多的分类,补充对应关键词再跑一遍。
3.2 第二步:给100题做难度分级
文档里通常不会标注每道题的难度,但你可以按以下几个客观指标自行分级。这样做的目的,是避免刷题时产生“假掌控感”——一直做简单题会觉得自己状态很好,上了考场才发现中等题还没碰过。
| 难度 | 判定标准 | 对应时间预算 |
|---|---|---|
| 简单 | 读完题5分钟内能想到思路,代码不超过50行 | 每题25分钟 |
| 中等 | 需要10到20分钟设计状态或搜索方向 | 每题45分钟 |
| 困难 | 需要拆解子问题或做多轮状态转移 | 每题60分钟,必要时先放弃 |
我判断难度比较“玄学”但有效:把题目数据范围看一眼,如果数组长度不超过1000且只需要排序、遍历、哈希查找,那基本是简单题;如果数据范围到10^5,还要求你只能用O(n)或O(n log n)的算法,那大概率是中等或困难题。数据规模是提示复杂度下限的线索,比直觉准得多。
分级后做一个统计,如果100题里中等题不到20道,说明这份文档偏基础,覆盖面可能不足。这时需要额外补充部分中等难度的模拟题,尤其是矩阵搜索和动态规划题,作为文档的补强项。反过来,如果困难题占比超过30%,基础薄弱的人先跳过去,优先把简单和中等的70道刷扎实,比死磕难题性价比更高。
3.3 第三步:40天三轮刷法时间表
把100题排进40天,每天只需要2小时左右就能完成。三轮刷法的设计思路是“先覆盖、再强化、后模拟”,避免刷到最后把前面的题全忘了。
| 阶段 | 天数 | 任务 | 每日题量 |
|---|---|---|---|
| 第一轮:覆盖 | 第1至15天 | 按知识点分组刷,简单题全做 | 7到8题 |
| 第二轮:强化 | 第16至30天 | 重做错题,中等题集中攻 | 4到5题 |
| 第三轮:模拟 | 第31至40天 | 随机抽题限时机考模拟 | 2到3题 |
第一轮是最痛苦的阶段,每天见的都是新题,但不要回头看答案。你会明显感觉到“刷了后面忘了前面”,这是正常现象,第二轮就是用来解决遗忘的。第二轮只处理两类题:第一轮中没做出来的、做出来但速度超过时间预算一半以上的。重做时不能凭记忆背答案,而是要重新推导思路,推不出来再看答案。
第三轮模拟要严格限时,用在线OJ或本机的编译器都行,关键是按机考规则来:一次读完三道题,不想清楚不写代码,每道题最多分配四十五分钟。常见误区是把模拟当成练习,写不出来就翻文档。这一轮的目的就是破坏这个坏习惯。
3.4 答案要“封底”:别让含答案变成看答案
“含答案”是文档最大的卖点,也是最容易让备考失效的地方。很多人打开文档后,题目下方紧接着就是题解和源码,视线很难忍住不上移。结果是自己完全没思考,只是顺着代码读了一遍,读完后觉得“我懂了”,合上文档一写就卡壳。
我的做法是:把每题答案所在的区域用书签折叠起来,或者复制题目到单独的编译文件里,做题时不打开原文档。只有两种情况允许看答案,一是某道题卡了30分钟以上没有思路;二是写完代码并且用例通过后对照检查是否有更优解。前者是止损,后者是提升,而“边做边看”是最浪费时间的刷法。
另外要提醒一点:文档中的答案不一定都是最优解,甚至有些有边界bug。我见过不止一次,某题答案代码能过样例,但换个输入就会数组越界或死循环。所以答案只能当作参考基准,别当成标准答案背,最终判断标准永远是你能在OJ上通过多少用例。
4. 机考实战:三道题的通用模板和输入输出处理
4.1 输入输出模板:Python版和C++版各一套
机考输入的常见形态有四种:单行整数、多行整数值、多行字符串、带分隔符的描述文本。处理这些输入有一套固定模板,提前准备好能省掉大量排查时间。下面是我常用的Python输入模板:
import sys def solve(): # 一次性读入所有行,按行切分 lines = [line.strip() for line in sys.stdin.readlines()] if not lines: return # 第一行通常是数据组数或数组长度,按题目含义解析 first_line = list(map(int, lines[0].split())) n = first_line[0] # 剩下的行按需遍历 arr = [] for i in range(1, n + 1): row = list(map(int, lines[i].split())) arr.append(row) # 核心算法写在这里 result = solve_core(arr) print(result) if __name__ == "__main__": solve()逻辑说明:一次性用sys.stdin.readlines()读入全部数据再按行切分,比逐行input()更快,也不会因为行尾空格出问题。strip()会把行首尾的空格和换行符去掉,避免首尾字段解析成空字符串。参数说明:first_line[0]是按“第一行是长度”的常见格式写的,但题目可能改成“第一行是n m”,表示二维网格行数和列数,这时要改为n, m = first_line[0], first_line[1]。
C++版本的模板差异不大,关键点在读取时忽略空格和换行:
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<vector<int>> grid(n, vector<int>(m)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> grid[i][j]; } } // 核心算法写在这里 cout << "result" << endl; return 0; }逻辑说明:ios::sync_with_stdio(false)和cin.tie(nullptr)这两行能让输入输出速度提升一大截,尤其是数据量到10^5以上时,不加这两行容易超时。参数说明:cin >> n >> m会自动跳过空白字符,所以不需要手动处理换行。这里有个细节,如果题目要求一行同时包含数字和字母混输(比如“3个苹果”),cin直接读整数就会失败,这种情况反而要用getline配合字符串切分。
4.2 三个必备代码模板:滑动窗口、DFS回溯、二分答案
100题里中等难度题目,很大比例落在滑动窗口、DFS回溯、二分答案这三类模型上。模板背熟之后,多数题可以直接套壳子改判断条件。
滑动窗口,常用于找满足条件的连续子数组或子串,核心是右指针扩张、左指针收缩:
def solve(nums, k): left = 0 window_sum = 0 ans = 0 for right in range(len(nums)): window_sum += nums[right] # 右指针扩张 while window_sum > k: # 不满足条件时收缩 window_sum -= nums[left] left += 1 ans = max(ans, right - left + 1) return ans逻辑说明:right每轮往右走一步,把新元素加进窗口;while循环负责在窗口和超限时从左边吐元素,保证窗口内始终满足约束;ans记录过程中满足条件的最大长度。参数说明:这里的约束条件是“和不超过k”,如果题目换成“乘积小于k”或“字符种类不超过k”,只需改while里的判断条件和收缩时的操作。
DFS回溯,常用于排列组合、地图搜索、路径枚举:
def dfs(grid, i, j): if (i < 0 or i >= len(grid) or j < 0 or j >= len(grid[0])): return if grid[i][j] == '0': return grid[i][j] = '0' # 标记已访问 for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]: dfs(grid, i + di, j + dj)逻辑说明:先做越界和访问判断,再标记当前节点为已访问,最后向四个方向递归。参数说明:grid[i][j] == '0'是按字符地图写的,如果地图里用整数0表示空地,把比较改成== 0即可。注意标记访问必须在递归前完成,否则会无限递归或重复计数。本题型在求连通块数量时,主函数里每发现一个未访问节点就调用一次dfs并计数。
二分答案,常用于最大化最小值、最小化最大值这类优化题:
def check(mid, nums, target): # 验证在当前假设值mid下,是否能满足条件 total = 0 for num in nums: total += max(0, mid - num) return total <= target def solve(nums, target): low, high = 0, max(nums) while low < high: mid = (low + high + 1) // 2 if check(mid, nums, target): low = mid else: high = mid - 1 return low逻辑说明:二分答案的核心是把“求最优值”转化成“给定一个值,判断是否可行”,然后在可行域上进行二分。参数说明:mid = (low + high + 1) // 2是向上取整,防止low和high相邻时死循环。check函数每次都要按整个数组跑一遍,所以整体复杂度是O(n log max),数据量在10^5级别时完全够用。
4.3 不会做时怎么保分:暴力解和部分分的合理时间窗口
考场上有两种情况需要保分策略:一种是题目完全没思路,另一种是想到了解法但不确定边界条件。无论哪种,第一优先级是先把暴力解写出来。暴力解的定义是:用最直观的方式枚举所有可能,不做任何时空优化。哪怕时间复杂度是O(n^2)甚至O(n^3),只要数据量小,测试用例能过的比例通常不低。
我见过的一道真题,求某个数组区间操作的最小值,期望解法是线段树或前缀最小值,但数据范围里有一部分测试用例数组长度不超过500。直接遍历所有区间的暴力写法,在这个规模下能跑完,于是拿到了这组用例的分。可见暴力不是丢人的写法,它是在时间紧迫时最可靠的保底手段。
保分时间窗口建议这样分配:如果一道题看了15分钟还没有任何思路,马上转暴力写法;如果暴力写法能跑通样例,再花10分钟检查数据范围,确认哪些用例会超时。如果数据范围大到必然超时,那就不要纠结,把暴力解法提交上去,保住部分分,把时间留给其他两道题。记住一个原则:空着不交是0分,暴力交上去至少有点分,考场上的目标是总分最大化。
5. 华为OD刷题避坑清单:文档答案、本地编译、考场规则里的5个坑
5.1 坑一:文档里的答案本地能过,OJ提交却是0分
现象:你照着文档里的代码逐行敲进IDE,本地测试样例输出完全正确,粘贴到OJ提交后结果是0分,甚至编译报错。原因通常有两个:一是文档代码存在平台差异,比如C++代码用了非标准头文件,本地编译器支持但OJ的编译环境不支持;二是提交时把调试用的打印语句和测试数据一起粘进去了。
解决:提交前做三件事,第一把printf/print等调试输出全部删掉;第二确认提交语言和代码块里的语言一致,别用Python代码冒充C++提交;第三把代码复制进一个空白编辑器里再提交,避免复制到行号或多余字符。如果编译都通过但用例全挂,检查是不是文件里漏了主函数调用。
5.2 坑二:只刷简单题,到了考场被中等题直接卡住
现象:文档100题刷完,简单题全对,一碰到中等题就没思路,考试时第二题卡了五十分钟,第三题基本没动。原因是很多人刷题时有舒适区倾向,简单题做完有成就感,中等题做不出来就跳过,最后100题可能只真正思考了其中40道。
解决:做题时做记录,每道题在“思路顺畅/思路卡顿/完全不会”三档里标一类。备考周期里,每天必须至少主动做一道思路卡顿的中等题。卡顿时间超过30分钟再看答案,但看完答案后当天晚上必须重写一遍,直到能独立通过所有用例。这个“强制中等题”的机制,是避免刷题刷成自欺欺人的关键。
5.3 坑三:把力扣模式当成机考模式练习
现象:平时练习都是打开编辑器直接写核心函数,不处理输入输出;换成机考形式后,光解析输入就花了二十分钟,脑袋瓜嗡嗡的。原因是输入输出解析是一种需要肌肉记忆的技能,不带这个环境练,上场就会手生。
解决:每周至少做三次完整输入输出练习,从第一行开始写,直到打印出正确结果。具体做法是随便从100题里抽几道题,刻意不复制模板,手写完整个处理流程。这个操作初期会耽误时间,但持续两周后,读取、切分、类型转换这类操作会变成条件反射,不再占用心智资源。
5.4 坑四:考试中途切屏或刷新页面被判违规
现象:考试过程中因为本地IDE代码太乱想切到浏览器看看文档,被考试系统判定为切屏次数过多,考试终止或成绩作废。原因是机考系统对切屏行为敏感,频繁切换窗口会被后台记录为作弊嫌疑。不同批次的规则略有差异,有些是警告,有些直接取消成绩。
解决:考试全程只保留一个浏览器窗口和一个代码编辑器窗口,所有材料提前打印或者提前决定不看。本地IDE建议使用离线编辑器,不要开聊天工具、浏览器、远程协助等任何可能触发焦点变化的程序。如果不小心切了一次屏,就立刻切回来,别反复切换。别指望求情,规则就是规则。
5.5 坑五:总分过了但单题得分太低,拿不到面试推进
现象:出分后总分合格,但第三题得分非常低,甚至为0,后续后台评估时被卡住。原因是OD机考总分固然重要,但部分部门会关注单题成绩分布,尤其是压轴题,用来判断候选人的算法上限。
解决:即使是保分策略,也尽量让第三题有点输出,不要空着。换个角度想,第三题写得暴力但逻辑正确,至少能过基础用例;如果完全空着,单题0分在评估时非常难看。备考时给自己定一个硬指标:简单题必须满分,中等题至少70%,困难题哪怕暴力也要能过样例并提交。这个目标比总分过线更稳健,也更能体现有能力完成实际开发任务的基本功。
6. 刷完100题后的自测清单:用这三个维度确认真的能上考场
刷完一遍100题,很多人不知道什么时候算“准备好了”。我的习惯是,不只看刷题数量,而是用三个维度做一次量化自测。
第一个维度是输入输出熟练度。随机抽10道题,不写核心算法,只写输入处理和输出打印,要求每道题在3分钟内完成并一次通过。做不到,就说明输入输出的反应速度还没达标,上考场会在第一题浪费大量时间。
第二个维度是单题限时通过率。从100题里随机抽三道,难度分别对应简单、中等、困难,限时150分钟完整作答,中间不允许看文档和答案。按机考规则判分后,如果总分换算下来能稳定超过你预计的通过线,并且中等题得分不低于70%,才算合格。不要用做过的原题,要打乱顺序抽,避免记忆答案造成假分数。
第三个维度是错题重做率。把备考过程中标记为“卡顿”和“不会”的题目整理成一个清单,在最后一周重做。重做通过率低于80%,说明第一轮的强化没有真正消化,需要针对性补漏。这个清单比100题本身更有价值,它是你知识盲区的精确切片。
| 自测维度 | 合格标准 | 未达标动作 |
|---|---|---|
| 输入输出 | 10题每题3分钟内完成 | 连续三天只练IO模板 |
| 模拟考 | 中等题得分不低于70% | 错题重做,不看答案 |
| 错题重做 | 重做通过率不低于80% | 按知识点集中回炉 |
我自己备考时一直有一个习惯:每周做一次全真模拟,模拟分数宁可低一点,也绝不中途看答案。这个习惯让我在真正考试时,面对陌生的困难题没有慌乱,而是按预案先暴力、再补边界、最后提交。机考的容错空间其实比你想象的大,前提是你在备考阶段就把状态调整到和真实考试一样的节奏。这一套流程走下来,你刷的就不只是100道题,而是一套能应对变化的能力。希望帮到你。
本文还有配套的精品资源,点击获取