1. 华为OD机试真题场景拆解:AGENTS.md 文件加载到底在考什么
华为OD机试里有一类题,表面看是字符串解析,实际考的是树形结构遍历。2026 年这道「返回所有加载的 AGENTS.md 文件 ID 列表」就是典型代表。题目背景是编码 Agent 工具会在项目目录下生成 AGENTS.md 文件记录上下文和规范,每个文件有唯一 ID,根文件 ID 为 0,其他文件除了自身 ID 还有父文件 ID。加载某个文件时要连带加载它所有子文件,要求输出目标文件及其全部子孙的 ID,升序排列。
这道题的核心检索词就是「华为OD机试 C++ DFS 返回所有加载的 AGENTS.md 文件ID列表」。它适合正在刷华为OD机试题库、准备机考的同学,尤其是目标院校一般、需要靠机试分数拉高竞争力的考生。题目本身难度中等,但有几个坑点:输入是逗号分隔的字符串需要手动解析、父子关系是「自身 ID 列表」和「父 ID 列表」一一对应、输出要升序、边界情况包括空目录和深层嵌套。
我试过把这道题当成单纯的数组题来做,结果在深层嵌套用例上翻车了。后来才意识到它本质是一棵树:父 ID 是父节点,自身 ID 是子节点,给定 target 就是求以它为根的子树所有节点。DFS 和 BFS 都能解,时间复杂度 O(n log n),n 最大 1000,完全够用。
下面我会先讲清楚建图和遍历的思路,再给出递归和迭代两版可复制的 C++ 代码,然后演示怎么用 TaoToken 统一 Key 在本地跑通调试和结果校验。整个流程你可以直接跟着操作,不需要额外环境配置的复杂步骤。
2. TaoToken 前置准备:统一 Key 跑通本地调试环境
刷华为OD机试的时候,很多人会遇到一个尴尬:本地写完代码想验证输出,但手头没有稳定的模型接口来辅助检查逻辑,或者要在多个工具之间来回切换 Key。TaoToken 在这里的作用是提供一个统一的 API Key,让你在本地调试 C++ 代码时,可以顺手用模型对话来核对边界用例、验证输出格式,不用为每个工具单独配一套凭证。
你需要先拿到一个可用的 Key。访问 API Keys 管理页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,登录后在控制台创建新的 API Key。这个 Key 就是后面所有调试请求的统一凭证。
拿到 Key 之后,本地调试的 Base URL 用 https://taotoken.net/api ,注意这个地址不带 UTM 参数,是纯 API 入口。Model ID 根据你用的模型填,比如 claude 系列或 gpt 系列,具体以控制台展示为准。这三件套——Base URL、Key、Model ID——是接入任何兼容 OpenAI 协议的工具的基础。
如果你更习惯在命令行里做代码验证,可以配合 Coding Plan 使用:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。它适合长期编码和 Agent 场景,把 Key 配进去之后,本地跑测试用例、让模型帮你检查 DFS 逻辑是否正确会顺畅很多。
这里要提醒一点:TaoToken 是 API 接入服务,不是编辑器替代品,你的 C++ 代码还是在本地 IDE 或命令行里编译运行,TaoToken 只负责提供模型能力来辅助你调试和校验。配置的时候把 Base URL 和 Key 填对,Model ID 选你需要的即可。
3. 可复制配置:C++ DFS 建图与遍历完整实现
这一节给出可以直接复制运行的配置和代码。先看目录结构示例,模拟题目里的 AGENTS.md 文件树:
project/ ├── AGENTS.md (ID=1, parent=0) ├── src/ │ ├── AGENTS.md (ID=2, parent=1) │ └── utils/ │ └── AGENTS.md (ID=4, parent=2) └── docs/ └── AGENTS.md (ID=3, parent=1) └── AGENTS.md (ID=5, parent=3)对应题目样例 1 的输入:自身 ID 列表1,2,3,4,5,父 ID 列表0,1,1,2,3,target=1,输出1,2,3,4,5。
下面是递归版 DFS 实现,代码可直接编译:
#include <iostream> #include <string> #include <vector> #include <algorithm> #include <sstream> #include <unordered_map> using namespace std; void dfs(int node, unordered_map<int, vector<int>>& children, vector<int>& result) { result.push_back(node); auto it = children.find(node); if (it != children.end()) { for (int child : it->second) { dfs(child, children, result); } } } vector<int> solveRecursive(const vector<int>& selfIds, const vector<int>& parentIds, int target) { unordered_map<int, vector<int>> children; for (size_t i = 0; i < selfIds.size(); i++) { children[parentIds[i]].push_back(selfIds[i]); } vector<int> result; dfs(target, children, result); sort(result.begin(), result.end()); return result; } vector<int> splitInts(const string& s) { vector<int> res; stringstream ss(s); string token; while (getline(ss, token, ',')) { if (!token.empty()) res.push_back(stoi(token)); } return res; } int main() { string line1, line2, line3; getline(cin, line1); getline(cin, line2); getline(cin, line3); vector<int> selfIds = splitInts(line1); vector<int> parentIds = splitInts(line2); int target = stoi(line3); vector<int> result = solveRecursive(selfIds, parentIds, target); for (size_t i = 0; i < result.size(); i++) { if (i > 0) cout << ","; cout << result[i]; } cout << endl; return 0; }迭代版用显式栈,避免深层嵌套时递归栈溢出:
vector<int> solveIterative(const vector<int>& selfIds, const vector<int>& parentIds, int target) { unordered_map<int, vector<int>> children; for (size_t i = 0; i < selfIds.size(); i++) { children[parentIds[i]].push_back(selfIds[i]); } vector<int> result; stack<int> st; st.push(target); while (!st.empty()) { int node = st.top(); st.pop(); result.push_back(node); auto it = children.find(node); if (it != children.end()) { for (int child : it->second) { st.push(child); } } } sort(result.begin(), result.end()); return result; }如果你用 Cline MCP 或类似工具做本地调试,配置片段可以写成这样,把三件套填进去:
{ "mcpServers": { "taotoken": { "url": "https://taotoken.net/api", "apiKey": "你的_API_KEY", "model": "claude-sonnet-4-20250514" } } }注意 Base URL 是https://taotoken.net/api,Key 从控制台复制,Model ID 按实际可用模型填。这三项缺一不可,配错任何一项都会导致请求失败。
4. 验证请求与成功结果:本地跑通样例与边界用例
代码写完之后,最关键的是验证。先跑题目给的两个样例。
样例 1 输入:
1,2,3,4,5 0,1,1,2,3 1预期输出1,2,3,4,5。编译运行:
g++ -std=c++17 -o agents agents.cpp echo "1,2,3,4,5 0,1,1,2,3 1" | ./agents实际输出1,2,3,4,5,和预期一致。
样例 2 输入:
2,5,7,9 1,2,2,0 2预期输出2,5,7。这里注意父 ID 列表里有 0,说明 ID=9 是根文件,但 target=2 不涉及它,所以结果只有 2 及其子孙 5、7。
边界用例要重点测三个。第一个是空目录场景,即 target 本身没有子节点:
1,2,3 0,1,1 3输出应该是3,因为 3 没有子节点。
第二个是深层嵌套,构造一条链:
1,2,3,4,5 0,1,2,3,4 1输出1,2,3,4,5,验证递归和迭代都能处理深度 5 的链。
第三个是重复 ID 的防御。题目保证 ID 唯一,但如果你自己造数据测试,可以在建图时加一个 set 去重,避免同一节点被多次加入结果。实测下来,标准用例不会触发这个问题,但养成防御习惯没坏处。
用 TaoToken 辅助校验时,可以把输入和你的输出贴给模型,让它帮你核对是否符合「升序、包含 target 及所有子孙」的规则。请求示例:
curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer 你的_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "输入 1,2,3,4,5 / 0,1,1,2,3 / 1,输出 1,2,3,4,5 是否正确?"}] }'返回的 choices 里会给出判断。如果返回结构里没有 choices 字段,说明请求格式或 Key 有问题,下一节会讲排查。
5. 本篇常见错排查:401、local proxy failed、reading choices 报错对照
刷题调试过程中,报错主要集中在接入层和代码层两类。下面按真实报错逐个对照。
401 Unauthorized:最常见。原因通常是 Key 没填、填错,或者请求头里Authorization格式不对。正确格式是Bearer 你的_API_KEY,注意 Bearer 和 Key 之间有一个空格。如果你用的是 Cline MCP 配置,检查apiKey字段是否复制完整,有没有多余空格或换行。
local proxy failed:这个报错一般出现在本地工具通过代理转发请求时。检查你的 Base URL 是否写成了https://taotoken.net/api,不要多加路径或斜杠。如果你在 settings 里配了额外的代理地址,先去掉,直接用官方 API 入口。另外确认本地网络能正常访问该地址,防火墙或公司网络策略可能拦截。
reading choices 报错 / choices 字段缺失:请求发出去了,但返回结构里没有choices,说明响应不是标准的 chat completions 格式。可能原因有三个:Model ID 填错导致服务端返回错误信息、请求体 JSON 格式不合法、或者用了不支持的参数。检查你的model字段是否和控制台展示的一致,messages是否是数组且每条有role和content。
OAuth 相关报错:如果你用的是 Claude Code 或 Codex 这类工具,可能会遇到 OAuth 认证失败。这类工具通常需要单独的认证流程,不要和 API Key 混用。如果你只是想用统一 Key 做调试,建议走 API Key 方式,在配置里明确填 Base URL、Key、Model ID 三件套。Codex 的auth.json里如果残留旧的 OAuth 凭证,先清空再填 API Key 配置。
输出格式错误:代码逻辑对了但输出不对,常见是忘了升序排序,或者 splitInts 没处理空 token。检查sort(result.begin(), result.end())是否调用,以及getline分割时是否过滤了空字符串。
深层嵌套栈溢出:递归版在极端深度下可能崩,换成迭代版即可。华为OD机试 n≤1000,递归一般不会溢出,但养成用迭代的习惯更稳。
排查顺序建议:先确认 Key 和 Base URL 正确,再确认 Model ID 可用,最后检查代码逻辑。接入问题看 API Keys 和接入文档:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,文档入口在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。
6. 语义一致收尾:把 DFS 模板迁移到其他目录树真题
这道「返回所有加载的 AGENTS.md 文件 ID 列表」的解法,本质是一个通用的「给定树中某节点,求其子树所有节点」模板。华为OD机试里类似的目录树、组织架构、依赖关系题都可以套这个思路:先把父子关系建成邻接表,再从 target 开始 DFS 或 BFS 收集,最后按题目要求排序输出。
你可以在本地把递归和迭代两版都跑一遍,对比结果是否一致。然后用 TaoToken 的模型对话功能,让它帮你生成几组随机测试数据,覆盖空目录、单链、多叉树三种形态,验证代码鲁棒性。模型对话入口:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 。
如果你准备长期刷题,把 Coding Plan 配好,统一 Key 之后本地调试和模型校验会省很多切换成本:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。最后提醒一句,机试通过后如果没收到面试邀请,主动联系 HR 查简历状态,别干等。刷题阶段把每道真题的边界用例都跑透,比盲目刷数量有用得多。