判断题:搜索 = 从初始状态出发,按某种规则逐步转移到新状态,直到找到目标状态或确定无解。
考点:搜索的定义(A1)。
解析:搜索 = 从初始状态出发,按转移规则逐步探索,直到找到目标状态或确定无解。✅ 正确
排除法:无(判断题)。混淆点:状态转移规则写错,搜索就在错误的空间里打转。
关联 · 搜索的三要素(A2):状态、转移、目标判断。
判断题:搜索的三要素:状态(当前局面怎么表示)、转移(一步能走到哪些状态)、目标判断(什么局面算找到答案)。
考点:搜索的三要素(A2)。
解析:状态(局面表示)、转移(一步可达哪些状态)、目标判断(什么算找到)。✅ 正确
排除法:无(判断题)。混淆点:三要素想清楚,代码就只剩 DFS/BFS 模板。
关联 · 深度优先搜索的概念(A3):按什么顺序探索由算法决定。
判断题:深度优先搜索(DFS)= 沿一条路径一路走到底,走不通再退回上一步换条路——不撞南墙不回头。
考点:深度优先搜索的概念(A3)。
解析:DFS = 一条路走到底、走不通再退回——"不撞南墙不回头"。✅ 正确
排除法:无(判断题)。混淆点:DFS 找到的第一条路径不保证最短(F1)。
关联 · DFS 的递归实现(B1):递归天然是 DFS。
判断题:广度优先搜索(BFS)= 一层一层向外扩展:先看距离起点 1 步的所有状态,再看 2 步的、3 步的……
考点:广度优先搜索的概念(A4)。
解析:BFS = 按层扩展:先 1 步的、再 2 步的……✅ 正确
排除法:无(判断题)。混淆点:按层扩展保证"第一次到达 = 最短步数"(C2)。
关联 · BFS 的队列实现(C1):队列保证按层。
单选题:DFS 与 BFS 实现时分别用什么数据结构保存"待访问的状态"?
考点:DFS 与 BFS 的容器(A5)。
解析:DFS 用栈(递归 = 系统栈)、BFS 用队列。正确答案 A。
排除法:B 说反;C/D 无依据——容器决定搜索顺序(P4)。
关联 · 栈实现 BFS(P4):容器换掉,顺序就变。
判断题:枚举、回溯、搜索一脉相承:枚举是最朴素的搜索;DFS/BFS 是通用的搜索框架;回溯 = DFS 加状态恢复。
考点:搜索与枚举回溯的关系(A6)。
解析:枚举是最朴素的搜索(第 11 章),DFS/BFS 是通用的搜索框架(本章),回溯 = DFS 加状态恢复(第 14 章)——三者一脉相承。✅ 正确
排除法:无(判断题)。混淆点:枚举/回溯/搜索不是并列的三个算法,而是同一思想的不同形态。
关联 · DFS 与回溯的关系(B7):回溯 = DFS + 状态恢复,本题是三章的总枢纽。
判断题:DFS 最常用递归实现——递归调用栈天然扮演"待访问栈"的角色,代码简洁。
考点:DFS 的递归实现(B1)。
解析:递归调用栈天然保存"还没探索的分支",DFS 用递归实现最简洁。✅ 正确
排除法:无(判断题)。混淆点:深度过大时递归会栈溢出(第 14 章),可用显式栈(B2)。
关联 · DFS 的显式栈实现(B2):递归与显式栈等价。
判断题:DFS 也可以用显式栈(stack)实现:把待访问节点压栈、循环弹栈访问——与递归版等价。
考点:DFS 的显式栈实现(B2)。
解析:用 stack 手动管理待访问节点,与递归版等价、且不受系统栈深度限制。✅ 正确
排除法:无(判断题)。混淆点:显式栈要自己处理"何时标记 visited"。
关联 · DFS 的访问标记(B3):两种实现都需要标记。
判断题:DFS 需要 visited 访问标记:防止重复访问节点、防止在有环的图中死循环。
考点:DFS 的访问标记(B3)。
解析:visited 防重复访问、防有环图死循环——DFS 的标配。✅ 正确
排除法:无(判断题)。混淆点:树(无环)可以不用,但图/网格必须用(P1)。
关联 · DFS 忘记访问标记(H1):没标记的后果。
判断题:DFS 先走到的分支会被完全探索完才回头——所以 DFS 的访问顺序是"先深入、后横向"。
考点:DFS 的搜索顺序(B4)。
解析:DFS 先探索完第一个分支才回头——先深入、后横向。✅ 正确
排除法:无(判断题)。混淆点:因此 DFS 输出顺序像"一头扎进去"(I3 vs J2)。
关联 · DFS 树先序输出(I1):顺序的代码体现。
判断题:DFS 适合:求一条可行路径、求所有解(配合回溯)、判断可达性、遍历整个图/网格。
考点:DFS 的适用场景(B5)。
解析:可行路径、所有解(回溯)、可达性、全图遍历。✅ 正确
排除法:无(判断题)。混淆点:最短路径不是 DFS 的强项(F1)。
关联 · 迷宫可行路径用 DFS(F2):只问"能不能到"用 DFS。
判断题:DFS 的空间取决于深度(递归栈深),深搜一条线时占用 。
考点:DFS 的空间复杂度(B6)。
解析:DFS 占空间的是递归栈(深度):。✅ 正确
排除法:无(判断题)。混淆点:窄而深的搜索 DFS 省空间;宽而浅的 BFS 更占空间(C5)。
关联 · BFS 的空间复杂度(C5):两者空间特性相反。
判断题:回溯 = DFS + 状态恢复(撤销选择)——第 14 章的回溯本质上就是 DFS。
考点:DFS 与回溯的关系(B7)。
解析:回溯 = DFS + 状态恢复——第 14 章的全排列/子集就是 DFS。✅ 正确
排除法:无(判断题)。混淆点:本章 DFS 偏图/网格遍历,回溯偏枚举所有方案。
关联 · 排列组合用 DFS 回溯(F3):应用场景的分工。
判断题:BFS 用队列实现:起点入队,循环"出队一个、把它的未访问邻居入队",先进先出保证按层扩展。
考点:BFS 的队列实现(C1)。
解析:起点入队 → 循环"出队 + 邻居入队",先进先出保证按层。✅ 正确
排除法:无(判断题)。混淆点:入队时就要标记 visited(H2/P2)。
关联 · BFS 出队顺序(J5):出队顺序 = 访问顺序。
判断题:无权图(每步代价相同)中,BFS 第一次到达某节点的步数就是最短步数——这是 BFS 最核心的性质。
考点:BFS 的层次与最短步数(C2)。
解析:无权图每步代价相同,BFS 第一次到达 = 最短路——最核心的性质。✅ 正确
排除法:无(判断题)。混淆点:带权图(边权不同)BFS 不再保证最短路。
关联 · BFS 最短距离(J3):dist 数组的由来。
判断题:BFS 常用 dist 数组记录每个节点到起点的最短距离:dist[起点] = 0,dist[邻居] = dist[当前] + 1。
考点:BFS 的距离数组(C3)。
解析:dist[起点] = 0,dist[邻居] = dist[当前] + 1——顺带完成最短路。✅ 正确
排除法:无(判断题)。混淆点:dist == -1 可兼作"未访问"标记,省一个数组。
关联 · BFS 最大层数(J4):dist 的最大值即层数。
判断题:BFS 适合:无权图最短路、最少步数、按层遍历(树的层序)、连通块扩散。
考点:BFS 的适用场景(C4)。
解析:无权最短路、最少步数、层序遍历、扩散。✅ 正确
排除法:无(判断题)。混淆点:所有解/回溯类问题别用 BFS(F5)。
关联 · 迷宫最短路径用 BFS(F1):最少步数场景。
判断题:BFS 的空间取决于宽度(队列最多同时保存一层/一圈的状态),可能远大于 DFS。
考点:BFS 的空间复杂度(C5)。
解析:队列最多存一层/一圈的状态:,可能远大于 DFS。✅ 正确
排除法:无(判断题)。混淆点:宽状态空间(如棋盘)BFS 会爆内存。
关联 · DFS 的空间复杂度(B6):深度 vs 宽度。
判断题:树的层序遍历 = BFS:一层访问完再访问下一层。
考点:BFS 的层级遍历(C6)。
解析:树的层序 = BFS:一层一层地出队。✅ 正确
排除法:无(判断题)。混淆点:第 9 章二叉树的层序遍历就是 BFS。
关联 · BFS 层序遍历输出(J1):代码版。
单选题:求"最少步数/最短路径"应该选?求"所有解/字典序最小解"通常选?
考点:DFS 与 BFS 的选择(C7)。
解析:最少步数/最短路 → BFS;所有解/字典序 → DFS(回溯)。正确答案 A。
排除法:B 说反;C/D 不考虑问题类型。
关联 · 最少步数与字典序(F5):按需求选算法。
判断题:网格问题中状态 = 格子坐标 (r, c);从一个格子走到相邻格子就是一次状态转移。
考点:网格图的状态(D1)。
解析:状态 = 坐标 (r, c);相邻格子的移动 = 状态转移。✅ 正确
排除法:无(判断题)。混淆点:有的题目状态还含方向、携带物等附加信息。
关联 · 网格问题与图问题(D7):网格即图。
单选题:四方向移动的标准写法是方向数组:dx[4] = {-1, 0, 1, 0}(上、右、下、左),对应的 dy[4] 是?
考点:四方向数组(D2)。
解析:dx = {-1, 0, 1, 0}(上下左右的行变化)配 dy = {0, 1, 0, -1}(列变化)。正确答案 A。
排除法:B/C 对应关系错位;D 是 dx 的重复。
关联 · 四方向可达格数(K1):方向数组的实战。
判断题:八方向 = 四方向 + 四个对角方向(左上、右上、左下、右下),常用于"斜着也算相邻"的题目。
考点:八方向数组(D3)。
解析:八方向 = 四方向 + 四对角,"斜着也算相邻"的场景用。✅ 正确
排除法:无(判断题)。混淆点:八方向的连通块比四方向更容易连成一片(K5)。
关联 · 八方向连通块(K5):八方向的实战。
判断题:网格搜索每次向邻居移动前必须检查边界(nr >= 0 && nr < n && nc >= 0 && nc < m),否则数组越界。
考点:网格的边界检查(D4)。
解析:每次移动前查 nr/nc 是否越界——不查就是数组越界(P3)。✅ 正确
排除法:无(判断题)。混淆点:边界检查写在访问数组之前,顺序不能反。
关联 · 网格越界(H3):越界的后果。
判断题:网格中的障碍物(墙/不可通行格)在转移时直接跳过:if (g[nr][nc] == 1) continue;。
考点:网格的障碍物(D5)。
解析:墙/不可通行格直接跳过:if (g[nr][nc] == 1) continue;。✅ 正确
排除法:无(判断题)。混淆点:障碍物判断常与边界判断写在同一行条件里。
关联 · 网格的访问标记(D6):两重过滤。
判断题:网格搜索同样需要访问标记(vis 二维数组或原地染色),防止同一个格子被反复访问导致死循环。
考点:网格的访问标记(D6)。
解析:vis 二维数组或原地染色,防止重复访问/死循环。✅ 正确
排除法:无(判断题)。混淆点:染色法省内存,但会破坏原图(需要原图时用 vis)。
关联 · 泛洪的标记方式(E5):两种标记方式。
判断题:网格问题就是图问题——每个格子是一个节点,相邻可通行的格子之间有一条边。
考点:网格问题与图问题(D7)。
解析:格子 = 节点、相邻可通行 = 边——网格搜索就是图搜索。✅ 正确
排除法:无(判断题)。混淆点:图论算法(连通块、最短路)都能搬到网格上。
关联 · 图的遍历回顾(F6):与第 10 章打通。
判断题:泛洪算法(Flood Fill)= 从起点开始,把与它连通的、满足条件的区域全部扩散标记,就像墨水扩散。
考点:泛洪算法的定义(E1)。
解析:从起点扩散,把连通且满足条件的区域全部标记——像墨水扩散。✅ 正确
排除法:无(判断题)。混淆点:泛洪 = DFS/BFS 的一种具体应用。
关联 · 泛洪与连通块(E2):主要用途。
判断题:泛洪的典型用途是连通块计数:遍历每个未访问的格子,每发起一次泛洪就是一个连通块。
考点:泛洪与连通块(E2)。
解析:遍历所有未访问格子,每发起一次泛洪 = 一个连通块,计数即得块数。✅ 正确
排除法:无(判断题)。混淆点:外层双重循环 + 内层泛洪是标准结构(M1)。
关联 · 泛洪岛屿计数(M1):代码版。
判断题:泛洪可以用 DFS(递归)或 BFS(队列)实现,两者结果相同。
考点:泛洪的实现方式(E3)。
解析:DFS(递归)或 BFS(队列)都行,结果相同。✅ 正确
排除法:无(判断题)。混淆点:网格很大时 DFS 递归可能爆栈,此时用 BFS。
关联 · BFS 泛洪可达数(L4):BFS 版泛洪。
判断题:泛洪的典型应用:岛屿数量、涂色(油漆桶)、连通区域面积/周长统计。
考点:泛洪的典型应用(E4)。
解析:岛屿数量、涂色(油漆桶)、连通区域面积/周长。✅ 正确
排除法:无(判断题)。混淆点:这些应用都是"连通区域"的变形。
关联 · 岛屿周长(M4):周长 = 边界的统计。
判断题:泛洪的标记有两种:vis 数组记录"已访问",或原地染色(把格子值改成别的数)省一个数组。
考点:泛洪的标记方式(E5)。
解析:vis 数组或原地染色(把格子改成别的数)。✅ 正确
排除法:无(判断题)。混淆点:染色后 g[nr][nc] != 1 同时兼任"已访问"判断。
关联 · DFS 泛洪染色(K4):染色法代码。
判断题:泛洪每个格子至多访问一次,复杂度 ( 个格子)。
考点:泛洪的复杂度(E6)。
解析:每格至多访问一次:。✅ 正确
排除法:无(判断题)。混淆点:配合外层循环仍是 (每格只泛洪一次)。
关联 · 搜索空间估算(G6):网格规模的估算。
判断题:迷宫求最短路径/最少步数必须用 BFS(DFS 找到的第一条路径不一定最短)。
考点:迷宫最短路径用 BFS(F1)。
解析:DFS 第一条路径不保证最短;BFS 按层扩展保证最短。✅ 正确
排除法:无(判断题)。混淆点:只问可行(不要求最短)时 DFS/BFS 皆可(F2)。
关联 · BFS 迷宫最短步数(L1):代码版。
判断题:迷宫只问"有没有一条路"(可行可达)时,DFS 和 BFS 都可以。
考点:迷宫可行路径用 DFS(F2)。
解析:只问"有没有路",DFS 和 BFS 都行——DFS 通常更省内存。✅ 正确
排除法:无(判断题)。混淆点:要输出一条具体路径时,DFS 的回溯结构更自然。
关联 · 迷宫可行判断(K2):DFS 判可达。
判断题:全排列、子集、组合这类"枚举所有方案"的问题用 DFS + 回溯(第 14 章内容)。
考点:排列组合用 DFS 回溯(F3)。
解析:全排列/子集/组合 = 枚举所有方案 = DFS + 回溯(第 14 章)。✅ 正确
排除法:无(判断题)。混淆点:这类问题没有"图",状态是"已选集合"。
关联 · DFS 与回溯的关系(B7):两章打通。
判断题:连通块数量(岛屿数)用泛洪:每发现一个未访问的格子就泛洪一次并计数。
考点:连通块计数用泛洪(F4)。
解析:岛屿数 = 泛洪计数。✅ 正确
排除法:无(判断题)。混淆点:并查集也能做,但泛洪更直观。
关联 · 泛洪与连通块(E2):同一个算法。
判断题:求最少步数用 BFS;求字典序最小/所有解用 DFS(按字典序方向枚举)——按需求选算法。
考点:最少步数与字典序(F5)。
解析:最少步数 → BFS;字典序最小/所有解 → DFS(方向按字典序枚举)。✅ 正确
排除法:无(判断题)。混淆点:DFS 按字典序枚举方向找到的第一个解即字典序最小。
关联 · DFS 与 BFS 的选择(C7):选算法的口诀。
判断题:第 10 章的图遍历(DFS/BFS + visited)就是搜索——本章把它们推广到网格、迷宫、状态空间。
考点:图的遍历回顾(F6)。
解析:第 10 章 DFS/BFS + visited 就是搜索,本章推广到网格/迷宫/状态空间。✅ 正确
排除法:无(判断题)。混淆点:图、树、网格、状态空间——统一的搜索框架。
关联 · 搜索的定义(A1):框架的起点。
判断题:搜索题的状态可以用多种方式表示——网格用坐标 (r, c)、图用节点编号、枚举用二进制 mask;选择"能装进数组、方便判重"的表示,是写搜索的第一步。
考点:状态的表示(G1)。
解析:网格用坐标 (r, c)、图用节点编号、子集枚举用二进制 mask——表示要能装进数组(判重/记录)且转移方便。✅ 正确
排除法:无(判断题)。混淆点:表示选得差(如状态存不下、判重不了),搜索代码会又难写又超时。
关联 · 网格图的状态(D1):坐标是最常用的状态表示。
判断题:写完搜索代码必查三点:边界判断在数组访问之前、visited 在进入(DFS)或入队(BFS)时就标记、终点判断写在正确位置。
考点:搜索代码的三个检查点(G2)。
解析:① 边界判断在访问数组之前(防越界,H3);② visited 进入/入队时就标记(防死循环/重复入队,H1/H2);③ 终点判断位置正确(先判再扩展)。✅ 正确
排除法:无(判断题)。混淆点:三个检查点对应本章 H 组的三个易错——写完代码逐条自查。
关联 · 搜索的常见错误(H 组):三个检查点各对应一个坑。
判断题:网格/图上的 DFS 递归深度过大时可能栈溢出,此时可改用 BFS 或显式栈实现——访问顺序可能不同,但能访问到的节点集合一致。
考点:深搜爆栈改用 BFS(G3)。
解析:递归深度过大 → 系统栈耗尽(第 14 章 A5);改用 BFS 或显式栈后,访问顺序可能不同,但能访问到的节点集合一致。✅ 正确
排除法:无(判断题)。混淆点:两种实现结果一致指的是"遍历的完整性",输出顺序不同是正常现象。
关联 · DFS 的显式栈实现(B2):显式栈版不占系统栈。
判断题:搜索顺序优化 = 先搜约束更强(可选更少)的分支——好的顺序能让搜索更快找到答案。
考点:搜索顺序优化(G4)。
解析:先搜可选少、约束强的分支,能更快找到答案——搜索顺序的选择技巧。✅ 正确
排除法:无(判断题)。混淆点:顺序只影响快慢、不影响最终结果。
关联 · 深度优先搜索的概念(A3):方向/分支顺序决定 DFS 的输出。
大纲注:本细节在 NOI 2025 大纲中未明确列出,属搜索实践的常用技巧。
判断题:BFS 求最短路的适用前提是每步代价相同(无权图/等权网格);边权不同的图不能直接用普通 BFS 求最短路。
考点:BFS 最短路的适用前提(G5)。
解析:BFS 第一次到达 = 最短路,前提是每步代价相同(无权图/等权网格);带权图上普通 BFS 不再保证最短路。✅ 正确
排除法:无(判断题)。混淆点:带权最短路需用其他算法(提高级内容),CSP-J 只要求掌握无权情形。
关联 · BFS 的层次与最短步数(C2):性质成立的前提就是本题。
判断题:搜索前先估算状态空间大小(如网格 、排列 、子集 ),判断是否会超时——超了就优化或换算法。
考点:搜索空间估算(G6)。
解析:先算状态空间(网格 、排列 、子集 ),估时间、决定优化或换算法。✅ 正确
排除法:无(判断题)。混淆点: 在 时基本超时——这就是"先估算再动手"的意义。
关联 · 搜索的三要素(A2):状态空间是搜索的地图。
大纲注:本细节在 NOI 2025 大纲中未明确列出,属搜索实践的常用技巧。
单选题:在有环的图上 DFS 忘记写 visited 标记,会发生?
考点:DFS 忘记访问标记(H1)。
解析:有环图无 visited → 在环里来回递归 → 栈溢出。正确答案 A。
排除法:B 只在树(无环)上成立;C 是正确写法;D 能编译。
关联 · 忘记访问标记的 DFS(P1):代码实证。
单选题:BFS 中节点入队时不标记 visited,会发生?
考点:BFS 忘记入队标记(H2)。
解析:入队时不标记 → 同一节点被多个邻居重复入队 → 队列爆炸/死循环。正确答案 A。
排除法:B/C 错误;D 能编译。
关联 · 忘记入队标记的 BFS(P2):代码实证。
单选题:网格搜索不检查边界,直接访问 g[nr][nc],会发生?
考点:网格越界(H3)。
解析:不判边界直接访问 g[nr][nc] → 越界,行为未定义。正确答案 A。
排除法:B/C 是幻想;D 能编译(运行时才越界)。
关联 · 网格的边界检查(D4):四重边界条件。
判断题:起点与终点重合时要特判(最短步数为 0);若忘记特判且 dist 初值设置不当,会输出错误答案。
考点:起点终点的特判(H4)。
解析:起点 = 终点时最短步数为 0,正确写法 dist[起点] = 0 先设好(P5)。✅ 正确
排除法:无(判断题)。混淆点:dist 初值 -1 且不设起点,会输出 -1 这种错误。
关联 · 起点等于终点(P5):正确代码输出 0。
判断题:以下结论全部正确——"DFS 一路走到底用栈、BFS 按层扩展用队列;无权图最短路用 BFS;连通块计数用泛洪;DFS/BFS 都要访问标记"。
考点:搜索综合判断(H5)。
解析:四句全部正确:DFS 栈、BFS 队列;无权最短路用 BFS;连通块用泛洪;两者都要访问标记。✅ 正确
排除法:无(判断题)。混淆点:这是本章骨架,逐条对照各组题目。
关联 · 搜索基本概念(A1):本章总结。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6]; // 邻接矩阵(1 下标),树:1 的孩子 2、3;2 的孩子 4、5 04void dfs(int u) { 05 cout << u << " "; // 先访问自己(先序) 06 for (int v = 1; v <= 5; v++) 07 if (g[u][v]) dfs(v); 08} 09int main() { 10 g[1][2] = g[1][3] = 1; 11 g[2][4] = g[2][5] = 1; 12 dfs(1); 13 return 0; 14}
单选题:程序输出是?
考点:DFS 树先序输出(I1)。
解析:先打印自己再递归孩子:1 → 2 → 4 → 5 → 3 → 输出 1 2 4 5 3。正确答案 A。
实现要点:DFS 框架 = cout << u + 遍历邻居递归。手算:沿递归链"进入一层打一层"。
排除法:B 是后序;C 是 BFS 层序;D 多了个 3(没有 visited 才会重复)。
关联 · DFS 的搜索顺序(B4):先序 = 进入序。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6]; // 树:1 的孩子 2、3;2 的孩子 4、5 04void dfs(int u) { 05 for (int v = 1; v <= 5; v++) 06 if (g[u][v]) dfs(v); 07 cout << u << " "; // 访问完孩子才打印(后序) 08} 09int main() { 10 g[1][2] = g[1][3] = 1; 11 g[2][4] = g[2][5] = 1; 12 dfs(1); 13 return 0; 14}
单选题:程序输出是?
考点:DFS 树后序输出(I2)。
解析:先递归完孩子再打印自己:4 5 2 3 1。正确答案 A。
实现要点:后序 = 递归调用之后打印。手算:最深的叶子先打印。
排除法:B 是先序;C 是层序;D 次序错。
关联 · DFS 树先序输出(I1):打印位置决定先/后序。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04void dfs(int u) { 05 vis[u] = 1; 06 cout << u << " "; 07 for (int v = 1; v <= 5; v++) 08 if (g[u][v] && !vis[v]) dfs(v); 09} 10int main() { 11 g[1][2] = g[1][3] = 1; // 边:1-2、1-3、2-4、2-5、3-5 12 g[2][4] = g[2][5] = g[3][5] = 1; 13 dfs(1); 14 return 0; 15}
单选题:程序输出是?
考点:DFS 图访问顺序(I3)。
解析:从 1 出发:1 → 2 → 4 → 5 →(3 从 5 回不来,回溯到 1)→ 3 → 输出 1 2 4 5 3。正确答案 A。
实现要点:图 DFS = visited 防重复 + 邻接矩阵按编号从小到大找邻居。手算:先深入、后横向。
排除法:B 是 BFS 序;C 是"1 先走 3"的另一种邻接顺序;D 次序错。
关联 · DFS 的访问标记(B3):visited 保证每点一次。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04void dfs(int u) { 05 vis[u] = 1; 06 cout << u << " "; 07 for (int v = 1; v <= 4; v++) 08 if (g[u][v] && !vis[v]) dfs(v); 09} 10int main() { 11 g[1][2] = g[2][3] = g[3][1] = 1; // 有环:1-2-3-1 12 g[3][4] = 1; // 还有边 3-4 13 dfs(1); 14 return 0; 15}
单选题:程序输出是?
考点:DFS 带访问标记(I4)。
解析:有环图:1 → 2 → 3 →(1 已访问跳过)→ 4 → 输出 1 2 3 4。正确答案 A。
实现要点:visited 在环图中拦截回边——没有它(P1)就是死循环。手算:遇到已访问节点直接跳过。
排除法:B(多了 1)是没标记的重复访问;C 漏了 4;D 多输出 1。
关联 · 忘记访问标记的 DFS(P1):本题的正确对照。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], dep = 0, mx = 0; 04void dfs(int u) { 05 dep++; 06 mx = max(mx, dep); // 记录最大递归深度 07 for (int v = 1; v <= 5; v++) 08 if (g[u][v]) dfs(v); 09 dep--; 10} 11int main() { 12 g[1][2] = g[1][3] = 1; // 树:1 的孩子 2、3;2 的孩子 4、5 13 g[2][4] = g[2][5] = 1; 14 dfs(1); 15 cout << mx; 16 return 0; 17}
单选题:程序输出是?
考点:DFS 递归深度(I5)。
解析:最深链 1-2-4(或 1-2-5),深度 = 3。正确答案 A。
实现要点:深度 = 进入加一、返回减一、max 记峰值(第 14 章 J5 同款)。手算:找最长的根到叶路径。
排除法:B(2)只到第二层;C(5)是节点数;D(4)无依据。
关联 · DFS 的空间复杂度(B6):深度决定栈空间。
01#include <bits/stdc++.h> 02using namespace std; 03int g[2][2] = {{0, 0}, {0, 0}}; // 2x2 网格,0 可走 04int cnt = 0; 05void dfs(int r, int c) { // 只能向右或向下走到 (1,1) 06 if (r == 1 && c == 1) { cnt++; return; } 07 if (r + 1 < 2) dfs(r + 1, c); // 向下 08 if (c + 1 < 2) dfs(r, c + 1); // 向右 09} 10int main() { dfs(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:DFS 网格路径计数(I6)。
解析:2×2 网格只能右/下:(0,0)→(1,0)→(1,1) 与 (0,0)→(0,1)→(1,1) → 2 条。正确答案 A。
实现要点:路径计数 = 到达终点 cnt++,每步两个方向分支。手算:画决策树。
排除法:B(1)漏一条;C(4)把两条路径重复计算;D(6)是 3×3 的答案(N6)。
关联 · 右下的路径计数(N1):同框架的 2×3 版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6], cnt = 0; 04void dfs(int u) { 05 vis[u] = 1; 06 cnt++; // 每访问一个节点计数 07 for (int v = 1; v <= 5; v++) 08 if (g[u][v] && !vis[v]) dfs(v); 09} 10int main() { 11 g[1][2] = g[2][4] = g[2][5] = 1; // 边:1-2、2-4、2-5(节点 3 孤立) 12 dfs(1); 13 cout << cnt; 14 return 0; 15}
单选题:程序输出是?
考点:DFS 可达节点数(I7)。
解析:从 1 可达 1、2、4、5(3 孤立)→ 4 个。正确答案 A。
实现要点:可达计数 = 每访问一个节点 cnt++。手算:圈出与起点连通的部分。
排除法:B(3)漏数起点;C(5)把孤立点也算上;D(2)只数了叶子。
关联 · DFS 的适用场景(B5):可达性判断。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 树:1 的孩子 2、3;2 的孩子 4、5 06 g[2][4] = g[2][5] = 1; 07 queue<int> q; 08 q.push(1); 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v]) q.push(v); 14 } 15 return 0; 16}
单选题:程序输出是?
考点:BFS 层序遍历输出(J1)。
解析:层序:1 → 2、3 → 4、5 → 1 2 3 4 5。正确答案 A。
实现要点:BFS 框架 = 起点入队 + 循环出队打印 + 邻居入队。手算:一层一层写。
排除法:B 是 DFS 先序;C 是"右孩子先"的变体;D 是倒序。
关联 · BFS 的层级遍历(C6):层序 = BFS。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 边:1-2、1-3、2-4、2-5、3-5 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; q.push(v); } 14 } 15 return 0; 16}
单选题:程序输出是?
考点:BFS 图访问顺序(J2)。
解析:1 → 2、3 → 4、5 → 1 2 3 4 5。正确答案 A。
实现要点:入队时立即标记 visited(否则 5 会被 2 和 3 重复入队)。手算:队列的变化 [1] → [2,3] → [3,4,5] → …。
排除法:B 是 DFS 序;C 是无标记的重复序;D 次序错。
关联 · BFS 忘记入队标记(H2):标记时机是本题的考点。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], dist[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 边:1-2、1-3、2-4、2-5、3-5 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 memset(dist, -1, sizeof dist); 08 queue<int> q; 09 q.push(1); dist[1] = 0; 10 while (!q.empty()) { 11 int u = q.front(); q.pop(); 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && dist[v] == -1) { 14 dist[v] = dist[u] + 1; 15 q.push(v); 16 } 17 } 18 cout << dist[5]; 19 return 0; 20}
单选题:程序输出是?
考点:BFS 最短距离(J3)。
解析:1→2/3 是 1 步,4/5 是 2 步 → d[5] = 2。正确答案 A。
实现要点:dist[v] = dist[u] + 1,dist == -1 兼作未访问。手算:逐层标距离。
排除法:B(1)误以为 5 与 1 直连;C(3)绕远;D(-1)是没访问到。
关联 · BFS 的距离数组(C3):dist 递推。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], dist[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 树:1 的孩子 2、3;2 的孩子 4、5 06 g[2][4] = g[2][5] = 1; 07 memset(dist, -1, sizeof dist); 08 queue<int> q; 09 q.push(1); dist[1] = 0; 10 int mx = 0; 11 while (!q.empty()) { 12 int u = q.front(); q.pop(); 13 mx = max(mx, dist[u]); 14 for (int v = 1; v <= 5; v++) 15 if (g[u][v] && dist[v] == -1) { dist[v] = dist[u] + 1; q.push(v); } 16 } 17 cout << mx; // 最大层数(根为第 0 层) 18 return 0; 19}
单选题:程序输出是?
考点:BFS 最大层数(J4)。
解析:层数:1(0 层)、2/3(1 层)、4/5(2 层)→ 最大 2。正确答案 A。
实现要点:mx = max(mx, dist[u])。手算:标出每层的节点。
排除法:B(1)只到第二层;C(3)把节点数当层数;D 无依据。
关联 · BFS 的层次与最短步数(C2):层 = 步数。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; // 出队顺序 = BFS 访问顺序 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; q.push(v); } 14 } 15 return 0; 16}
单选题:程序输出是?
考点:BFS 出队顺序(J5)。
解析:出队顺序 = BFS 访问顺序:1 2 3 4 5。正确答案 A。
实现要点:出队时打印 = 访问序。手算:跟踪队列进出。
排除法:B 是 DFS 序;C/D 次序错。
关联 · BFS 的队列实现(C1):队列决定顺序。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], dist[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 边:1-2、1-3、2-4、2-5、3-5 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 memset(dist, -1, sizeof dist); 08 queue<int> q; 09 q.push(2); dist[2] = 0; // 多源:2 和 3 都是起点 10 q.push(3); dist[3] = 0; 11 while (!q.empty()) { 12 int u = q.front(); q.pop(); 13 for (int v = 1; v <= 5; v++) 14 if (g[u][v] && dist[v] == -1) { dist[v] = dist[u] + 1; q.push(v); } 15 } 16 cout << dist[5]; // 到最近源的距离 17 return 0; 18}
单选题:程序输出是?
考点:BFS 多源最近距离(J6)。
解析:源点 2、3 距离 0;5 与 2、3 都相邻 → d[5] = 1。正确答案 A。
实现要点:多源 BFS = 所有源点先入队(dist 置 0)。手算:多个起点同时向外扩散。
排除法:B(2)是单源(从 1 出发)的距离;C(0)是源点自身;D 无依据。
关联 · BFS 多源距离(L2):网格版多源。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6], pre[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; // 边:1-2、1-3、2-4、2-5、3-5 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 if (u == 5) break; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; pre[v] = u; q.push(v); } 14 } 15 vector<int> path; 16 for (int x = 5; x != 1; x = pre[x]) path.push_back(x); // 从 5 回溯到 1 17 path.push_back(1); 18 for (int i = path.size() - 1; i >= 0; i--) cout << path[i] << " "; 19 return 0; 20}
单选题:程序输出是?
考点:BFS 路径重建(J7)。
解析:pre 记录来路:5 ← 2 ← 1(BFS 先经 2 到达 5)→ 路径 1 2 5。正确答案 A。
实现要点:pre[v] = u 在入队时记录 + 从终点回溯到起点 + 反转输出。手算:沿 pre 链回溯。
排除法:B 是 5 经 3 的路径(BFS 先入队的是 2 的路径);C 绕远;D 不存在的直连。
关联 · BFS 最短路径重建(N3):网格版同款。
01#include <bits/stdc++.h> 02using namespace std; 03int g[5][5] = { 04 {0,0,0,0,0}, 05 {0,1,1,1,0}, 06 {0,1,0,1,0}, 07 {0,0,0,1,0}, 08 {0,1,0,0,0}}; // 0 可走,1 是墙 09int vis[5][5], cnt = 0; 10int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 上右下左 11void dfs(int r, int c) { 12 vis[r][c] = 1; 13 cnt++; 14 for (int k = 0; k < 4; k++) { 15 int nr = r + dx[k], nc = c + dy[k]; 16 if (nr < 0 || nr >= 5 || nc < 0 || nc >= 5) continue; 17 if (g[nr][nc] == 1 || vis[nr][nc]) continue; 18 dfs(nr, nc); 19 } 20} 21int main() { dfs(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:四方向可达格数(K1)。
解析:从 (0,0) 四方向可达的可走格:第 0 行 5 个、第 1 行 2 个(c0、c4)、第 2 行 3 个(c0、c2、c4)、第 3 行 4 个(c0~c2、c4)、第 4 行 4 个(c0、c2~c4)→ 共 18 个。正确答案 A。
实现要点:网格 DFS = 方向数组 + 边界/墙/visited 三重过滤 + 计数。手算:从起点开始"墨水扩散",逐格数。
排除法:B(16)漏数两格;C(20)多数;D(25)是全部格子(含墙)。
关联 · 四方向数组(D2):方向数组实战。
01#include <bits/stdc++.h> 02using namespace std; 03int g[5][5] = { 04 {0,0,0,0,0}, 05 {0,1,1,1,0}, 06 {0,1,0,1,0}, 07 {0,0,0,1,0}, 08 {0,1,0,0,0}}; 09int vis[5][5]; 10int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 11void dfs(int r, int c) { 12 vis[r][c] = 1; 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 5 || nc < 0 || nc >= 5) continue; 16 if (g[nr][nc] == 1 || vis[nr][nc]) continue; 17 dfs(nr, nc); 18 } 19} 20int main() { 21 dfs(0, 0); 22 cout << (vis[4][4] ? "YES" : "NO"); // 终点 (4,4) 可达? 23 return 0; 24}
单选题:程序输出是?
考点:迷宫可行判断(K2)。
解析:终点 (4,4) 可达(路径绕右侧到达)→ YES。正确答案 A。
实现要点:DFS 后检查 vis[终点]。手算:跟踪 DFS 覆盖的区域。
排除法:B 是"不可达";C/D 不是输出。
关联 · 迷宫可行路径用 DFS(F2):只问可达用 DFS。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // 3x3 全可走 04int vis[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 上右下左 06void dfs(int r, int c) { 07 vis[r][c] = 1; 08 cout << r << c << " "; // 输出访问到的格子(行列拼写) 09 for (int k = 0; k < 4; k++) { 10 int nr = r + dx[k], nc = c + dy[k]; 11 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 12 if (vis[nr][nc]) continue; 13 dfs(nr, nc); 14 } 15} 16int main() { dfs(0, 0); return 0; }
单选题:程序输出是?
考点:DFS 网格访问顺序(K3)。
解析:方向顺序(上右下左)DFS:00 → 01 → 02 → 12 → 22 → 21 → 11 → 10 → 20。正确答案 A。
实现要点:DFS 访问序 = 方向数组的顺序决定邻居尝试次序。手算:按"上右下左"优先级一路深入。
排除法:B 是行优先扫描序;C 是 11 与 10 次序错;D 是"下"优先的序。
关联 · DFS 的搜索顺序(B4):方向顺序影响输出。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,1,0},{0,0,0}}; // (1,1) 是墙 04int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 05void dfs(int r, int c) { 06 g[r][c] = 2; // 原地染色:访问过改成 2 07 for (int k = 0; k < 4; k++) { 08 int nr = r + dx[k], nc = c + dy[k]; 09 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 10 if (g[nr][nc] != 0) continue; // 只走 0(可走且未染色) 11 dfs(nr, nc); 12 } 13} 14int main() { 15 dfs(0, 0); 16 for (int i = 0; i < 3; i++) { 17 for (int j = 0; j < 3; j++) cout << g[i][j] << " "; 18 cout << endl; 19 } 20 return 0; 21}
单选题:程序输出是?
考点:DFS 泛洪染色(K4)。
解析:从 (0,0) 染色所有可走格(8 个),墙 (1,1) 不变 → 三行 2 2 2、2 1 2、2 2 2。正确答案 A。
实现要点:原地染色 = g[r][c] = 2 + 只走 g[nr][nc] == 0。手算:染色 = 把走过的 0 改成 2。
排除法:B 把墙也染了(条件 != 1 的错);C 是原图(没染);D 只染了一部分。
关联 · 泛洪的标记方式(E5):染色法。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{1,1,0},{0,0,0},{0,0,1}}; // 1 是陆地 04int vis[3][3]; 05int dx[8] = {-1,-1,-1,0,0,1,1,1}, dy[8] = {-1,0,1,-1,1,-1,0,1}; // 八方向 06void dfs(int r, int c) { 07 vis[r][c] = 1; 08 for (int k = 0; k < 8; k++) { 09 int nr = r + dx[k], nc = c + dy[k]; 10 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 11 if (g[nr][nc] == 0 || vis[nr][nc]) continue; 12 dfs(nr, nc); 13 } 14} 15int main() { 16 int cnt = 0; 17 for (int i = 0; i < 3; i++) 18 for (int j = 0; j < 3; j++) 19 if (g[i][j] == 1 && !vis[i][j]) { cnt++; dfs(i, j); } 20 cout << cnt; 21 return 0; 22}
单选题:程序输出是?
考点:八方向连通块(K5)。
解析:陆地 (0,0)-(0,1) 相连(一个块),(2,2) 单独 → 2 个连通块。正确答案 A。
实现要点:八方向数组 + 外层循环计数。手算:数"斜着也算相邻"的陆地团。
排除法:B(1)把对角也误连了;C(3)多数;D 无依据。
关联 · 八方向数组(D3):八方向实战。
01#include <bits/stdc++.h> 02using namespace std; 03int g[2][2] = {{0,1},{1,0}}; // 只有 (0,0) 和 (1,1) 可走(对角) 04int vis[2][2], cnt = 0; 05int dx[8] = {-1,-1,-1,0,0,1,1,1}, dy[8] = {-1,0,1,-1,1,-1,0,1}; // 八方向 06void dfs(int r, int c) { 07 vis[r][c] = 1; 08 cnt++; 09 for (int k = 0; k < 8; k++) { 10 int nr = r + dx[k], nc = c + dy[k]; 11 if (nr < 0 || nr >= 2 || nc < 0 || nc >= 2) continue; 12 if (g[nr][nc] == 1 || vis[nr][nc]) continue; 13 dfs(nr, nc); 14 } 15} 16int main() { dfs(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:八方向可达数(K6)。
解析:2×2 网格只有 (0,0)、(1,1) 可走,八方向下 (1,1) 是对角可达 → 2 格。正确答案 A。
实现要点:八方向允许对角跳跃(四方向下本题只有 1 格)。手算:斜着一步也能走。
排除法:B(1)是四方向的结果;C(4)是全部格子;D 无依据。
关联 · 四方向可达格数(K1):方向数量改变可达性。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][4] = {{1,1,0,0},{1,0,0,1},{0,0,1,0}}; // 1 是陆地 04int vis[3][4]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 四方向 06void dfs(int r, int c) { 07 vis[r][c] = 1; 08 for (int k = 0; k < 4; k++) { 09 int nr = r + dx[k], nc = c + dy[k]; 10 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 4) continue; 11 if (g[nr][nc] == 0 || vis[nr][nc]) continue; 12 dfs(nr, nc); 13 } 14} 15int main() { 16 int cnt = 0; 17 for (int i = 0; i < 3; i++) 18 for (int j = 0; j < 4; j++) 19 if (g[i][j] == 1 && !vis[i][j]) { cnt++; dfs(i, j); } 20 cout << cnt; 21 return 0; 22}
单选题:程序输出是?
考点:岛屿计数(K7)。
解析:四方向岛屿:(0,0)(0,1)(1,0) 一块、(1,3) 一块、(2,2) 一块 → 3 块。正确答案 A。
实现要点:泛洪计数 = 外层双循环 + 每发现陆地 cnt++ 并泛洪。手算:逐块圈出来。
排除法:B(2)漏数一块;C(4)多数;D 无依据。
关联 · 泛洪与连通块(E2):标准结构。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{1,1,0},{0,0,0}}; // 0 可走,1 是墙 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; 10 while (!q.empty()) { 11 auto [r, c] = q.front(); q.pop(); 12 for (int k = 0; k < 4; k++) { 13 int nr = r + dx[k], nc = c + dy[k]; 14 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 15 if (g[nr][nc] == 1 || dist[nr][nc] != -1) continue; 16 dist[nr][nc] = dist[r][c] + 1; 17 q.push({nr, nc}); 18 } 19 } 20 cout << dist[2][2]; // 从 (0,0) 到 (2,2) 的最短步数 21 return 0; 22}
单选题:程序输出是?
考点:BFS 迷宫最短步数(L1)。
解析:绕右侧:00 → 01 → 02 → 12 → 22 → 4 步。正确答案 A。
实现要点:BFS + dist 数组,终点 dist 即答案。手算:按层扩散到终点。
排除法:B(2)是直线距离;C(6)绕远;D(-1)不可达。
关联 · BFS 的层次与最短步数(C2):最短路性质。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // 3x3 全可走 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; // 两个源点 10 q.push({2, 2}); dist[2][2] = 0; 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 cout << dist[1][1]; // 到最近源点的距离 22 return 0; 23}
单选题:程序输出是?
考点:BFS 多源距离(L2)。
解析:两个源 (0,0)、(2,2) 同时扩散,(1,1) 到最近源距离 2。正确答案 A。
实现要点:多源 BFS = 所有源先入队。手算:两处墨水同时扩散、相遇即最近。
排除法:B(1)是单源从 (0,0) 到 (1,1) 的距离;C(4)是最远距离;D(0)是源点。
关联 · BFS 多源最近距离(J6):图版多源。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; 10 int mx = 0; 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 mx = max(mx, dist[r][c]); // 最大层数 14 for (int k = 0; k < 4; k++) { 15 int nr = r + dx[k], nc = c + dy[k]; 16 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 17 if (dist[nr][nc] != -1) continue; 18 dist[nr][nc] = dist[r][c] + 1; 19 q.push({nr, nc}); 20 } 21 } 22 cout << mx; 23 return 0; 24}
单选题:程序输出是?
考点:BFS 网格层数(L3)。
解析:3×3 从 (0,0):最远 (2,2) 距离 4 → 最大层数 4。正确答案 A。
实现要点:mx = max(mx, dist[r][c])。手算:数曼哈顿最远的格子。
排除法:B(2)只到中心;C(3)漏一层;D(8)是格子数。
关联 · BFS 最大层数(J4):图版层数。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{1,1,0},{0,0,0}}; 04int dist[3][3], cnt = 0; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; 10 while (!q.empty()) { 11 auto [r, c] = q.front(); q.pop(); 12 cnt++; // 统计访问到的格子数 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (g[nr][nc] == 1 || dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 cout << cnt; 22 return 0; 23}
单选题:程序输出是?
考点:BFS 泛洪可达数(L4)。
解析:墙挡左下,从 (0,0) 可达 7 个可走格。正确答案 A。
实现要点:BFS 出队计数 = 可达数。手算:扩散圈出可达区域。
排除法:B(9)是全部格子;C(5)漏两格;D(4)是到终点的距离。
关联 · 泛洪的实现方式(E3):BFS 版泛洪。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{1,1,0},{0,0,0}}; 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; 10 while (!q.empty()) { 11 auto [r, c] = q.front(); q.pop(); 12 for (int k = 0; k < 4; k++) { 13 int nr = r + dx[k], nc = c + dy[k]; 14 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 15 if (g[nr][nc] == 1 || dist[nr][nc] != -1) continue; 16 dist[nr][nc] = dist[r][c] + 1; 17 q.push({nr, nc}); 18 } 19 } 20 cout << dist[2][0]; // 从 (0,0) 到 (2,0) 的最短步数 21 return 0; 22}
单选题:程序输出是?
考点:BFS 路径长度(L5)。
解析:到 (2,0) 需绕右侧:00→01→02→12→22→21→20 → 6 步。正确答案 A。
实现要点:dist[目标] 即最短步数。手算:绕墙走。
排除法:B(4)是到 (2,2) 的距离;C(2)是直线距离;D(-1)不可达。
关联 · BFS 迷宫最短步数(L1):同图不同终点。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; 04int dist[3][3]; 05// 换一种方向顺序:左、下、右、上 06int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0}; 07int main() { 08 memset(dist, -1, sizeof dist); 09 queue<pair<int,int>> q; 10 q.push({0, 0}); dist[0][0] = 0; 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 cout << dist[2][2]; // 最短距离与方向顺序有关吗? 22 return 0; 23}
单选题:程序输出是?
考点:方向顺序与最短路(L6)。
解析:换方向顺序(左下右上),最短距离仍是 4——BFS 最短路与方向顺序无关。正确答案 A。
实现要点:方向顺序只影响访问次序、不影响 dist。手算:按新顺序扩散,距离不变。
排除法:B/C/D 都错——本题教学点就是"顺序无关"。
关联 · DFS 网格访问顺序(K3):DFS 的输出才依赖方向顺序。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; // BFS 部分 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; q.push(v); } 14 } 15 return 0; 16}
单选题:程序输出是?(同图的 DFS 顺序为 1 2 4 5 3)
考点:DFS 与 BFS 的对比(L7)。
解析:同图 BFS 输出 1 2 3 4 5(DFS 是 1 2 4 5 3)。正确答案 A。
实现要点:同图两序对照——DFS 一头扎进、BFS 一层铺开。手算:两棵树各画一遍。
排除法:B 是 DFS 序;C/D 是其他变体。
关联 · DFS 与 BFS 的选择(C7):两序的含义。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][4] = {{1,1,0,0},{1,0,0,1},{0,0,1,0}}; 04int vis[3][4]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06void flood(int r, int c) { 07 vis[r][c] = 1; 08 for (int k = 0; k < 4; k++) { 09 int nr = r + dx[k], nc = c + dy[k]; 10 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 4) continue; 11 if (g[nr][nc] == 0 || vis[nr][nc]) continue; 12 flood(nr, nc); 13 } 14} 15int main() { 16 int cnt = 0; 17 for (int i = 0; i < 3; i++) 18 for (int j = 0; j < 4; j++) 19 if (g[i][j] == 1 && !vis[i][j]) { cnt++; flood(i, j); } 20 cout << cnt; // 岛屿数量 21 return 0; 22}
单选题:程序输出是?
考点:泛洪岛屿计数(M1)。
解析:四方向岛屿 3 块:(0,0)(0,1)(1,0)、(1,3)、(2,2)。正确答案 A。
实现要点:外层双循环 + 泛洪 + 计数(与 K7 同构)。手算:逐块圈出。
排除法:B(2)漏一块;C(4)多数;D 无依据。
关联 · 泛洪岛屿计数(E2):标准结构。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{1,1,0},{0,1,0},{0,1,1}}; 04int vis[3][3], sz = 0; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06void flood(int r, int c) { 07 vis[r][c] = 1; 08 sz++; // 本连通块大小 09 for (int k = 0; k < 4; k++) { 10 int nr = r + dx[k], nc = c + dy[k]; 11 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 12 if (g[nr][nc] == 0 || vis[nr][nc]) continue; 13 flood(nr, nc); 14 } 15} 16int main() { 17 int mx = 0; 18 for (int i = 0; i < 3; i++) 19 for (int j = 0; j < 3; j++) 20 if (g[i][j] == 1 && !vis[i][j]) { sz = 0; flood(i, j); mx = max(mx, sz); } 21 cout << mx; // 最大连通块大小 22 return 0; 23}
单选题:程序输出是?
考点:泛洪最大连通块(M2)。
解析:陆地 (0,0)(0,1)(1,1)(2,1)(2,2) 连成一块、大小 5。正确答案 A。
实现要点:泛洪时统计块大小 sz++,取 max。手算:圈出最大的一片。
排除法:B(4)漏一块;C(3)只数了一行;D(6)多数。
关联 · 泛洪岛屿计数(M1):计数升级为大小统计。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{1,1,0},{1,0,0},{0,0,0}}; // 1 是陆地 04int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 05void flood(int r, int c) { 06 g[r][c] = 2; // 原地染色 07 for (int k = 0; k < 4; k++) { 08 int nr = r + dx[k], nc = c + dy[k]; 09 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 10 if (g[nr][nc] != 1) continue; // 只染陆地 11 flood(nr, nc); 12 } 13} 14int main() { 15 flood(0, 0); 16 for (int i = 0; i < 3; i++) { 17 for (int j = 0; j < 3; j++) cout << g[i][j] << " "; 18 cout << endl; 19 } 20 return 0; 21}
单选题:程序输出是?
考点:泛洪涂色输出(M3)。
解析:从 (0,0) 染色相连陆地 → 第一行 2 2 0、第二行 2 0 0、第三行全 0。正确答案 A。
实现要点:染色只染 g == 1 的陆地(!= 1 不染)。手算:圈出与起点相连的陆地。
排除法:B 多染了 (1,1)(实际是 0);C 是原图;D 次序错。
关联 · DFS 泛洪染色(K4):染色法同款。
01#include <bits/stdc++.h> 02using namespace std; 03int g[2][2] = {{1,1},{1,0}}; // 3 块陆地 04int vis[2][2], ans = 0; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06void flood(int r, int c) { 07 vis[r][c] = 1; 08 for (int k = 0; k < 4; k++) { 09 int nr = r + dx[k], nc = c + dy[k]; 10 if (nr < 0 || nr >= 2 || nc < 0 || nc >= 2) { ans++; continue; } // 边界算周长 11 if (g[nr][nc] == 0) ans++; // 靠海一边算周长 12 else if (!vis[nr][nc]) flood(nr, nc); 13 } 14} 15int main() { flood(0, 0); cout << ans; return 0; }
单选题:程序输出是?
考点:岛屿周长(M4)。
解析:每块陆地数"靠海/出界"的边:(0,0) 2 边、(0,1) 3 边、(1,0) 3 边 → 周长 8。正确答案 A。
实现要点:周长 = 每个陆地格对四个方向数"出界或邻居是海"的次数。手算:逐格数外边。
排除法:B(6)漏数;C(10)多数;D(4)是单格周长。
关联 · 泛洪的典型应用(E4):周长统计。
01#include <bits/stdc++.h> 02using namespace std; 03int g[4][4] = {{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}}; // 4x4 全陆地 04int vis[4][4], cnt = 0; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06void flood(int r, int c) { 07 vis[r][c] = 1; 08 if (r == 0 || c == 0 || r == 3 || c == 3) cnt++; // 统计边界格 09 for (int k = 0; k < 4; k++) { 10 int nr = r + dx[k], nc = c + dy[k]; 11 if (nr < 0 || nr >= 4 || nc < 0 || nc >= 4) continue; 12 if (vis[nr][nc]) continue; 13 flood(nr, nc); 14 } 15} 16int main() { flood(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:泛洪边界格统计(M5)。
解析:4×4 全陆地,边界格 = 外围一圈 = 12 格。正确答案 A。
实现要点:泛洪中判断 r == 0 || c == 0 || r == 3 || c == 3 计数。手算:数外圈。
排除法:B(16)是全部格子;C(4)是一行;D(8)是两圈的一半。
关联 · 泛洪的复杂度(E6):每格访问一次。
01#include <bits/stdc++.h> 02using namespace std; 03int g[2][3] = {{0,0,0},{0,0,0}}; // 2 行 3 列 04int cnt = 0; 05void dfs(int r, int c) { // 只能向右或向下,从 (0,0) 到 (1,2) 06 if (r == 1 && c == 2) { cnt++; return; } 07 if (r + 1 < 2) dfs(r + 1, c); 08 if (c + 1 < 3) dfs(r, c + 1); 09} 10int main() { dfs(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:右下的路径计数(N1)。
解析:2×3 网格从 (0,0) 到 (1,2),只向右/下:路径 = 组合数 。正确答案 A。
实现要点:DFS 两分支(右/下)+ 终点计数。手算:RDR、DRR、RRD 三种。
排除法:B(2)是 2×2 的答案(I6);C(6)是 3×3 的答案(N6);D 无依据。
关联 · DFS 网格路径计数(I6):同框架不同尺寸。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; 04int dist[3][3], level[10] = {0}; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 0}); dist[0][0] = 0; 10 while (!q.empty()) { 11 auto [r, c] = q.front(); q.pop(); 12 level[dist[r][c]]++; // 统计每层的格子数 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 for (int i = 0; i <= 4; i++) cout << level[i] << " "; 22 return 0; 23}
单选题:程序输出是?
考点:BFS 分层输出(N2)。
解析:3×3 从 (0,0) 各层格子数:1、2、3、2、1。正确答案 A。
实现要点:level[dist]++ 统计每层。手算:按曼哈顿距离分层。
排除法:B 漏了最后一层;C 第 4 层应是 1;D 漏输出第 4 层。
关联 · BFS 网格层数(L3):层数的分布版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,1,0},{0,0,0}}; // (1,1) 是墙 04int dist[3][3]; 05pair<int,int> pre[3][3]; 06int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 07int main() { 08 memset(dist, -1, sizeof dist); 09 queue<pair<int,int>> q; 10 q.push({0, 0}); dist[0][0] = 0; 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (g[nr][nc] == 1 || dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 pre[nr][nc] = {r, c}; 19 q.push({nr, nc}); 20 } 21 } 22 vector<pair<int,int>> path; 23 for (auto p = make_pair(2, 2); p != make_pair(0, 0); p = pre[p.first][p.second]) 24 path.push_back(p); // 从终点回溯 25 path.push_back({0, 0}); 26 for (int i = path.size() - 1; i >= 0; i--) 27 cout << path[i].first << path[i].second << " "; 28 return 0; 29}
单选题:程序输出是?
考点:BFS 最短路径重建(N3)。
解析:墙在 (1,1),最短路径绕右侧:00 01 02 12 22。正确答案 A。
实现要点:pre[nr][nc] = {r, c} + 终点回溯 + 反转输出。手算:沿 pre 链从终点走回起点。
排除法:B 绕左侧(更长);C 缺中间格;D 穿墙了。
关联 · BFS 路径重建(J7):图版同款。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // 3x3 全可走 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 queue<pair<int,int>> q; 09 q.push({0, 2}); dist[0][2] = 0; // 两个出口先入队(多源 BFS) 10 q.push({2, 0}); dist[2][0] = 0; 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 cout << dist[1][1]; // 从 (1,1) 到最近出口的步数 22 return 0; 23}
单选题:程序输出是?
考点:多出口迷宫最近距离(N4)。
解析:两个出口 (0,2)、(2,0) 作为源点同时 BFS:(0,1) 与 (1,2) 距离 1,(1,1) 由它们扩展到距离 2。正确答案 A。
实现要点:多出口最近距离 = 把所有出口先入队的多源 BFS,dist[起点] 即到最近出口的步数。手算:从出口向外一圈圈扩散,看第几圈碰到 (1,1)。
排除法:B(1)误以为 (1,1) 与出口相邻(实际距离都是 2);C/D 无依据。
关联 · BFS 多源最近距离(J6):同款多源框架的网格版。
01#include <bits/stdc++.h> 02using namespace std; 03int main() { 04 int n = 3; // 3 个物品,每个选/不选 05 int cnt = 0; 06 for (int mask = 0; mask < (1 << n); mask++) cnt++; // mask 的每一位代表一个物品 07 cout << cnt; // 子集总数 08 return 0; 09}
单选题:程序输出是?
考点:二进制枚举子集(N5)。
解析: 时 mask 从 0 到 ,共 8 个子集。正确答案 A。
实现要点:1 << n = 子集总数,mask 每一位 = 一个物品选/不选。手算:。
排除法:B(3)是物品数;C(6)是排列数;D(7)是 。
关联 · 枚举子集(第 11 章 B3):二进制枚举 = 子集枚举的标准写法。
01#include <bits/stdc++.h> 02using namespace std; 03int cnt = 0; 04void dfs(int r, int c) { // 3x3 网格,只能向右或向下(限定方向) 05 if (r == 2 && c == 2) { cnt++; return; } 06 if (r + 1 < 3) dfs(r + 1, c); 07 if (c + 1 < 3) dfs(r, c + 1); 08} 09int main() { dfs(0, 0); cout << cnt; return 0; }
单选题:程序输出是?
考点:限定方向的路径计数(N6)。
解析:3×3 只向右/下到 (2,2):路径数 。正确答案 A。
实现要点:每个位置只有"向右/向下"两个转移分支(方向受限),DFS 计数到终点。手算:组合数公式核对 。
排除法:B(3)是 2×3 的答案(N1);C(9)是格子数;D 无依据。
关联 · 右下的路径计数(N1):同框架不同尺寸。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04void dfs(int u) { 05 vis[u] = 1; 06 cout << u << " "; 07 for (int v = 1; v <= 5; v++) 08 if (g[u][v] && !vis[v]) ______; // 递归访问邻居 09} 10int main() { 11 g[1][2] = g[1][3] = 1; 12 g[2][4] = g[2][5] = g[3][5] = 1; 13 dfs(1); 14 return 0; 15}
单选题:横线处应填入?
考点:补全 DFS 递归调用(O1)。
解析:递归访问邻居,填 dfs(v)。运行输出 1 2 4 5 3。正确答案 A。
实现要点:DFS 框架 = 标记 + 打印 + 对每个未访问邻居递归调用。手算:沿递归链走。
排除法:B(dfs(u))死递归;C 只标记不递归;D 提前返回。
关联 · DFS 图访问顺序(I3):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04void dfs(int u) { 05 ______; // 标记当前节点已访问 06 cout << u << " "; 07 for (int v = 1; v <= 5; v++) 08 if (g[u][v] && !vis[v]) dfs(v); 09} 10int main() { 11 g[1][2] = g[1][3] = 1; 12 g[2][4] = g[2][5] = g[3][5] = 1; 13 dfs(1); 14 return 0; 15}
单选题:横线处应填入?
考点:补全访问标记(O2)。
解析:进入即标记当前节点,填 vis[u] = 1。运行输出 1 2 4 5 3。正确答案 A。
实现要点:标记在递归最前面(防重复 + 防环)。手算:标记顺序与访问顺序一致。
排除法:B 是清除标记;C 标错对象;D 与访问无关。
关联 · DFS 的访问标记(B3):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (______) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; q.push(v); } 14 } 15 return 0; 16}
单选题:横线处应填入?
考点:补全 BFS 循环(O3)。
解析:队列非空就继续,填 !q.empty()。运行输出 1 2 3 4 5。正确答案 A。
实现要点:BFS 主循环 = 队列空即结束。手算:出队到队列空。
排除法:B 条件反(一次都不跑);C 漏最后一个;D 是终止条件的误解。
关联 · BFS 的队列实现(C1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { 14 vis[v] = 1; // 入队时立即标记 15 ______; 16 } 17 } 18 return 0; 19}
单选题:横线处应填入?
考点:补全入队标记(O4)。
解析:标记后入队,填 q.push(v)。运行输出 1 2 3 4 5。正确答案 A。
实现要点:入队前标记 + 入队两行配套——防止重复入队(H2)。
排除法:B(q.pop)在空循环外弹出会错;C 混入 DFS;D 重复入队起点。
关联 · BFS 忘记入队标记(H2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int dx[4] = {-1, 0, 1, 0}; // 上、右、下、左 04int dy[4] = ______; 05int main() { 06 // 用 dx/dy 实现网格四方向移动 07 return 0; 08}
单选题:横线处应填入?
考点:补全方向数组(O5)。
解析:上(-1,0)、右(0,1)、下(1,0)、左(0,-1)→ 填 {0, 1, 0, -1}。正确答案 A。
实现要点:dx 与 dy 逐位对应:第 k 个方向 = (dx[k], dy[k])。手算:四个方向逐一核对。
排除法:B 对应"右上下左";C 对应"上下右左"错位;D 是 dx 的重复。
关联 · 四方向数组(D2):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{1,1,0},{1,0,0},{0,0,1}}; 04int vis[3][3], cnt = 0; 05void flood(int r, int c) { 06 if (r < 0 || r >= 3 || c < 0 || c >= 3) return; 07 if (g[r][c] == 0 || vis[r][c]) return; 08 vis[r][c] = 1; 09 flood(r + 1, c); flood(r - 1, c); 10 flood(r, c + 1); flood(r, c - 1); 11} 12int main() { 13 for (int i = 0; i < 3; i++) 14 for (int j = 0; j < 3; j++) 15 if (g[i][j] == 1 && !vis[i][j]) { ______; flood(i, j); } 16 cout << cnt; 17 return 0; 18}
单选题:横线处应填入?
考点:补全连通块计数(O6)。
解析:发现新块先计数再泛洪,填 cnt++。运行输出 2。正确答案 A。
实现要点:外层双循环 + cnt++ + 泛洪——连通块计数标准结构。手算:两块陆地。
排除法:B(cnt = 0)每块清零;C 清标记;D 只泛洪不计数。
关联 · 泛洪岛屿计数(M1):填空版。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6]; 04void dfs(int u) { 05 // 错误:没有 visited 标记 06 cout << u << " "; 07 for (int v = 1; v <= 3; v++) 08 if (g[u][v]) dfs(v); 09} 10int main() { 11 g[1][2] = g[2][3] = g[3][1] = 1; // 有环:1-2-3-1 12 dfs(1); 13 return 0; 14}
单选题:程序会发生什么?
考点:忘记访问标记的 DFS(P1)。
解析:环 1-2-3-1 无 visited → 无限递归 → 栈溢出。正确答案 A。
实现要点:visited 是 DFS 正确性的前提(H1)。手算:追踪几层就发现循环。
排除法:B 只在无环时成立;C 是正确写法;D 能编译。
关联 · DFS 忘记访问标记(H1):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 queue<int> q; 08 q.push(1); vis[1] = 1; 09 while (!q.empty()) { 10 int u = q.front(); q.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { 14 // 错误:入队前没有 vis[v] = 1(出队时才标记) 15 q.push(v); 16 } 17 } 18 return 0; 19}
单选题:程序会发生什么?
考点:忘记入队标记的 BFS(P2)。
解析:5 被 2 和 3 分别入队两次,输出重复、队列膨胀。正确答案 A。
实现要点:入队时标记(不是出队时)——两个邻居看到同一节点时只有第一个能入队。手算:跟踪 5 的两次入队。
排除法:B 错——有重复;C 能编译;D 正是"无重复"(本题有)。
关联 · BFS 忘记入队标记(H2):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int g[2][2] = {{0,0},{0,0}}; 04int vis[2][2]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06void dfs(int r, int c) { 07 vis[r][c] = 1; 08 for (int k = 0; k < 4; k++) { 09 int nr = r + dx[k], nc = c + dy[k]; 10 // 错误:缺少边界检查 11 if (vis[nr][nc]) continue; 12 dfs(nr, nc); 13 } 14} 15int main() { dfs(0, 0); return 0; }
单选题:程序会发生什么?
考点:网格越界访问(P3)。
解析:vis[-1][..] 等越界下标 → 行为未定义。正确答案 A。
实现要点:边界检查必须写在访问之前(D4)。手算:从 (0,0) 向上走就出界。
排除法:B/C 是幻想;D 能编译。
关联 · 网格越界(H3):概念题代码化。
01#include <bits/stdc++.h> 02using namespace std; 03int g[6][6], vis[6]; 04int main() { 05 g[1][2] = g[1][3] = 1; 06 g[2][4] = g[2][5] = g[3][5] = 1; 07 stack<int> st; // 错误:把 BFS 的队列换成了栈 08 st.push(1); vis[1] = 1; 09 while (!st.empty()) { 10 int u = st.top(); st.pop(); 11 cout << u << " "; 12 for (int v = 1; v <= 5; v++) 13 if (g[u][v] && !vis[v]) { vis[v] = 1; st.push(v); } 14 } 15 return 0; 16}
单选题:程序输出是?
考点:栈实现 BFS(P4)。
解析:栈后进先出:1 → 3 → 5 → 2 → 4 → 输出 1 3 5 2 4(变成 DFS 序)。正确答案 A。
实现要点:容器决定顺序——队列 = BFS、栈 = DFS。手算:栈顶弹出一个、压入其邻居。
排除法:B 是队列序;C 是递归 DFS 序(邻接顺序不同);D 次序错。
关联 · DFS 与 BFS 的容器(A5):容器与算法绑定。
01#include <bits/stdc++.h> 02using namespace std; 03int g[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; 04int dist[3][3]; 05int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; 06int main() { 07 memset(dist, -1, sizeof dist); 08 int sr = 1, sc = 1, tr = 1, tc = 1; // 起点 = 终点 09 queue<pair<int,int>> q; 10 q.push({sr, sc}); dist[sr][sc] = 0; // 起点的距离先设为 0 11 while (!q.empty()) { 12 auto [r, c] = q.front(); q.pop(); 13 for (int k = 0; k < 4; k++) { 14 int nr = r + dx[k], nc = c + dy[k]; 15 if (nr < 0 || nr >= 3 || nc < 0 || nc >= 3) continue; 16 if (dist[nr][nc] != -1) continue; 17 dist[nr][nc] = dist[r][c] + 1; 18 q.push({nr, nc}); 19 } 20 } 21 cout << dist[tr][tc]; 22 return 0; 23}
单选题:程序输出是?
考点:起点等于终点(P5)。
解析:起点 = 终点,(1,1) 的 dist 一开始就设 0,BFS 后仍是 0 → 输出 0。正确答案 A。
实现要点:dist[起点] = 0 先设置(不是 -1),特判自然完成。手算:起点即终点、步数 0。
排除法:B(-1)是"没设起点距离"的错误写法;C/D 无依据。
关联 · 起点终点的特判(H4):正确写法示范。