林老师 · 客观题题库 · 第 29 章 并查集与字典树 · 知识细节练习

第 29 章 并查集与字典树 · 知识细节练习

100 题 · 每题对应一个知识细节 · 全部原创
真题
复刻
试卷编号ORIG-第29章并查集与字典树-知识细节练习
题目总数100 题 · 100 分
试卷类型客观题
考生须知:
① 本卷共 16 大部分,合计 100 题 · 100 分,全部为客观题;
② 试卷右上角设有 「提交答卷」「重置考试」 按钮,提交后系统自动判分并显示答题正确情况,请确认全部作答后再行提交;
③ 试卷不显示答案,提交后方可查看每题作答与正确答案的对照;
④ 答卷进度会保留在本地缓存中,刷新或再次打开仍可继续作答;
⑤ 本卷仅供学生练习使用;请勿用于其他用途;题面有问题请联系:i64coder@163.com。

判 分 报 告

0 / 100 分
0
答 对 · 得 0
0
答 错 · 失 0
当前筛选下没有题目

并查集概念

6 QUESTIONS · 2 POINTS EACH
第 1 题 A1 未作答

并查集(Union-Find / 不相交集)主要解决?

(1 分)
第 2 题 A2 未作答

并查集的两个基本操作是?

(1 分)
第 3 题 A3 未作答

并查集的常见实现是?

(1 分)
第 4 题 A4 未作答

带路径压缩与按秩合并的并查集,单次操作复杂度是?

(1 分)
第 5 题 A5 未作答

并查集的典型应用是?

(1 分)
第 6 题 A6 未作答

判断题:并查集与线段树/树状数组解决的问题完全不同——并查集管"集合关系"、后两者管"区间信息"。

(1 分)

find 与路径压缩

7 QUESTIONS · 2 POINTS EACH
第 7 题 B1 未作答

find(x) 的作用是?

(1 分)
第 8 题 B2 未作答

判断题:朴素 find 沿父链一路向上——若树退化成链(1→2→3→…→n),find(1) 要 O(n)O(n) 步。

(1 分)
第 9 题 B3 未作答

路径压缩的递归版 find 是?

(1 分)
第 10 题 B4 未作答

判断题:路径压缩也可写成迭代——先找到根、再让沿途节点全部指向根(两次遍历)。

(1 分)
第 11 题 B5 未作答

判断题:路径压缩把树压扁——find 一次后,路径上所有节点的父都直接是根,后续 find 接近 O(1)O(1)

(1 分)
第 12 题 B6 未作答

判断题:路径压缩递归版的关键细节是赋值——fa[x] = find(fa[x]) 把返回的根写回 fa[x]。

(1 分)
第 13 题 B7 未作答

判断题:find 的返回值恒是"代表元"——同一集合内所有元素 find 结果相同。

(1 分)

union 与按秩合并

7 QUESTIONS · 2 POINTS EACH
第 14 题 C1 未作答

union(x, y) 的作用是?

(1 分)
第 15 题 C2 未作答

union 的标准写法是?

(1 分)
第 16 题 C3 未作答

按秩合并(union by rank)是?

(1 分)
第 17 题 C4 未作答

按大小合并(union by size)是?

(1 分)
第 18 题 C5 未作答

判断题:按秩/按大小合并保证树高 O(logn)O(\log n)——每次挂接后树高至多加 1,且小树挂大树不增加大树的秩。

(1 分)
第 19 题 C6 未作答

判断题:路径压缩 + 按秩合并双优化后,mm 次操作总复杂度 O(mα(n))O(m \cdot \alpha(n))——反阿克曼函数增长极慢,实际视为常数。

(1 分)
第 20 题 C7 未作答

判断题:union 前先 find 两元素——已在同一集合则无需合并(也防止自环)。

(1 分)

并查集应用

7 QUESTIONS · 2 POINTS EACH
第 21 题 D1 未作答

用并查集判定两节点是否连通,做法是?

(1 分)
第 22 题 D2 未作答

判断题:连通块数 = 合并完成后"根是自身"的节点数——每次有效 union 使块数减 1。

(1 分)
第 23 题 D3 未作答

无向图判环的并查集做法是?

(1 分)
第 24 题 D4 未作答

Kruskal 最小生成树中并查集的作用是?

(1 分)
第 25 题 D5 未作答

判断题:Kruskal = 边排序 + 并查集判环——并查集是 Kruskal 正确性的关键组件。

(1 分)
第 26 题 D6 未作答

判断题:并查集还用于——亲戚关系、等价类合并、区间染色(反向并查集)、食物链(带权并查集)。

(1 分)
第 27 题 D7 未作答

判断题:并查集的核心价值 = 高效维护"同一组"关系——一切"合并+查同组"的问题都适用。

(1 分)

字典树概念

6 QUESTIONS · 2 POINTS EACH
第 28 题 E1 未作答

字典树(Trie)的定义是?

(1 分)
第 29 题 E2 未作答

Trie 主要解决?

(1 分)
第 30 题 E3 未作答

Trie 的节点通常包含?

(1 分)
第 31 题 E4 未作答

Trie 插入/查询长度为 LL 的字符串的复杂度是?

(1 分)
第 32 题 E5 未作答

Trie 与哈希表的正确对比是?

(1 分)
第 33 题 E6 未作答

Trie 的典型应用是?

(1 分)

Trie 操作

6 QUESTIONS · 2 POINTS EACH
第 34 题 F1 未作答

Trie 插入字符串的过程是?

(1 分)
第 35 题 F2 未作答

判断题:查询完整单词 = 逐字符走边,全部走通且末节点有结束标记才算存在。

(1 分)
第 36 题 F3 未作答

判断题:前缀查询 = 逐字符走边,全部走通即"存在以该前缀开头的单词"(不需要结束标记)。

(1 分)
第 37 题 F4 未作答

判断题:Trie 删除单词 = 找到末节点去掉结束标记;若整条路径无其他单词可回收节点。

(1 分)
第 38 题 F5 未作答

判断题:Trie 节点存"经过次数"计数——插入时路径上所有节点计数 +1,可统计"以某前缀开头的单词数"。

(1 分)
第 39 题 F6 未作答

判断题:Trie 三大操作 = 插入、查询、前缀统计——都沿"逐字符走边"的同一框架。

(1 分)

综合与选择

6 QUESTIONS · 2 POINTS EACH
第 40 题 G1 未作答

判断题:并查集与线段树/树状数组/Trie 解决的问题正交——按"集合关系/区间信息/字符串前缀"三分类选结构。

(1 分)
第 41 题 G2 未作答

需要"统计以 'ab' 为前缀的单词数",选?

(1 分)
第 42 题 G3 未作答

判断题:选择矩阵——同组关系用并查集、前缀查询用 Trie、精确查找用哈希、区间信息用线段树系。

(1 分)
第 43 题 G4 未作答

判断题:复杂度总表——并查集近 O(1)O(1)、Trie O(L)O(L)(L 为串长)、哈希平均 O(1)O(1)——各擅胜场。

(1 分)
第 44 题 G5 未作答

判断题:并查集空间 O(n)O(n)、Trie 空间 O(总字符数×字符集)O(总字符数 \times 字符集)——Trie 空间消耗大是其主要缺点。

(1 分)
第 45 题 G6 未作答

需要"动态合并集合 + 查询同组",选?

(1 分)

易错综合

5 QUESTIONS · 2 POINTS EACH
第 46 题 H1 未作答

判断题:只写 return fa[x] 的 find(无压缩)在链状退化时单次 O(n)O(n)——大量操作会超时。

(1 分)
第 47 题 H2 未作答

判断题:union 不做按秩合并,最坏树高可达 O(n)O(n)——即使有路径压缩也不如双优化稳定。

(1 分)
第 48 题 H3 未作答

判断题:Trie 用"子节点下标 0 表示空"时,节点编号从 1 开始——0 号留作空标志,混用会误判。

(1 分)
第 49 题 H4 未作答

判断题:并查集使用前必须初始化 fa[i] = i——忘初始化导致所有 find 结果错乱。

(1 分)
第 50 题 H5 未作答

判断题:以下结论全部正确——"find 带路径压缩;union 按秩合并防退化;并查集初始化 fa[i]=i;Trie 逐字符走边、0 下标作空标志;前缀查询不需结束标记"。

(1 分)

find 代码

6 QUESTIONS · 2 POINTS EACH
第 51 题 I1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};   // 链:1→2→3→4→5
04int find(int x) {
05    while (fa[x] != x) x = fa[x];  // 朴素 find(无压缩)
06    return x;
07}
08int main() {
09    cout << find(1);
10    return 0;
11}

单选题:程序输出是?(元素 1 所在集合的根)

(1 分)
第 52 题 I2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);   // 路径压缩
06}
07int main() {
08    find(1);
09    cout << fa[1] << " " << fa[2] << " " << fa[3] << " " << fa[4];
10    return 0;
11}

单选题:程序输出是?(find(1) 后沿途节点的父节点——全部被压到根)

(1 分)
第 53 题 I3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    int steps = 0;
06    while (fa[x] != x) { x = fa[x]; steps++; }
07    return steps;
08}
09int main() {
10    cout << find(1);
11    return 0;
12}

单选题:程序输出是?(链 1→2→3→4→5 中 find(1) 的步数)

(1 分)
第 54 题 I4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    return ______;               // 路径压缩递归版
06}
07int main() {
08    find(1);
09    cout << fa[1];
10    return 0;
11}

单选题:横线处应填入?(使输出为 5

(1 分)
第 55 题 I5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    find(1);
09    int steps = 0, x = 1;
10    while (fa[x] != x) { x = fa[x]; steps++; }   // 压缩后再次 find(1) 的步数
11    cout << steps;
12    return 0;
13}

单选题:程序输出是?(路径压缩后 find(1) 只需 1 步)

(1 分)
第 56 题 I6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[7] = {0, 1, 1, 2, 3, 4, 6};   // 1←2←3←4←5、6 独立
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    find(5);
09    cout << find(1) << " " << find(5) << " " << find(6);
10    return 0;
11}

单选题:程序输出是?(三个集合的代表元)

(1 分)

union 代码

6 QUESTIONS · 2 POINTS EACH
第 57 题 J1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(1)] = find(2);     // union(1,2)
10    fa[find(2)] = find(3);     // union(2,3)
11    cout << find(1) << " " << find(3);
12    return 0;
13}

单选题:程序输出是?(合并后 1 与 3 是否同集合)

(1 分)
第 58 题 J2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6], rk[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07void uni(int x, int y) {
08    int rx = find(x), ry = find(y);
09    if (rx == ry) return;
10    if (rk[rx] < rk[ry]) fa[rx] = ry;      // 矮挂高
11    else if (rk[rx] > rk[ry]) fa[ry] = rx;
12    else { fa[rx] = ry; rk[ry]++; }        // 等高时挂后秩 +1
13}
14int main() {
15    for (int i = 1; i <= 4; i++) { fa[i] = i; rk[i] = 0; }
16    uni(1, 2); uni(3, 4); uni(1, 3);
17    cout << find(1) << " " << find(4);
18    return 0;
19}

单选题:程序输出是?(按秩合并:uni(1,2) 后 1 挂 2;uni(3,4) 后 3 挂 4;uni(1,3) 时两树等高 → 2 挂 4)

(1 分)
第 59 题 J3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6], sz[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07void uni(int x, int y) {
08    int rx = find(x), ry = find(y);
09    if (rx == ry) return;
10    if (sz[rx] < sz[ry]) swap(rx, ry);     // 小挂大
11    fa[ry] = rx; sz[rx] += sz[ry];
12}
13int main() {
14    for (int i = 1; i <= 5; i++) { fa[i] = i; sz[i] = 1; }
15    uni(1, 2); uni(3, 4); uni(1, 3);
16    cout << sz[find(1)];
17    return 0;
18}

单选题:程序输出是?(合并后集合 {1,2,3,4} 的大小)

(1 分)
第 60 题 J4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    ______;                     // union(1, 3):把 1 的根挂到 3 的根
10    cout << find(1) << " " << find(3);
11    return 0;
12}

单选题:横线处应填入?(使输出为 3 3

(1 分)
第 61 题 J5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(2)] = find(1);     // 2 挂到 1
10    fa[find(3)] = find(1);     // 3 挂到 1
11    fa[find(4)] = find(2);     // 4 挂到 2
12    cout << fa[2] << " " << fa[3] << " " << fa[4];
13    return 0;
14}

单选题:程序输出是?(2、3 挂 1;4 挂到 find(2)——此时 2 已挂 1,故 4 也挂 1)

(1 分)
第 62 题 J6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(1)] = find(2);
10    fa[find(2)] = find(3);
11    fa[find(4)] = find(5);
12    fa[find(5)] = find(3);     // 合并两个集合
13    int cnt = 0;
14    for (int i = 1; i <= 5; i++) if (find(i) == i) cnt++;
15    cout << cnt;
16    return 0;
17}

单选题:程序输出是?(最终连通块数)

(1 分)
拾壹

并查集应用代码

7 QUESTIONS · 2 POINTS EACH
第 63 题 K1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(1)] = find(2);
10    fa[find(3)] = find(4);
11    cout << (find(1) == find(3) ? "CONNECTED" : "NOT-CONNECTED");
12    return 0;
13}

单选题:程序输出是?

(1 分)
第 64 题 K2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[7];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 6; i++) fa[i] = i;
09    fa[find(1)] = find(2);    // {1,2}
10    fa[find(3)] = find(4);    // {3,4}
11    fa[find(5)] = find(6);    // {5,6}
12    int cnt = 0;
13    for (int i = 1; i <= 6; i++) if (find(i) == i) cnt++;
14    cout << cnt;
15    return 0;
16}

单选题:程序输出是?(6 个元素分成 3 组后的连通块数)

(1 分)
第 65 题 K3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[4];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 3; i++) fa[i] = i;
09    bool cycle = false;
10    int e[3][2] = {{1, 2}, {2, 3}, {1, 3}};   // 三条边
11    for (int i = 0; i < 3; i++) {
12        int x = e[i][0], y = e[i][1];
13        if (find(x) == find(y)) cycle = true;
14        else fa[find(x)] = find(y);
15    }
16    cout << (cycle ? "CYCLE" : "NO-CYCLE");
17    return 0;
18}

单选题:程序输出是?(三角形三边成环)

(1 分)
第 66 题 K4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    // 亲戚关系:1 与 2、2 与 3、4 与 5 是亲戚
10    fa[find(1)] = find(2);
11    fa[find(2)] = find(3);
12    fa[find(4)] = find(5);
13    cout << (find(1) == find(3) ? "YES" : "NO") << " "
14         << (find(3) == find(5) ? "YES" : "NO");
15    return 0;
16}

单选题:程序输出是?(1 与 3 是亲戚、3 与 5 不是)

(1 分)
第 67 题 K5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[5];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 4; i++) fa[i] = i;
09    // 边按权升序:(1,2,1) (3,4,1) (2,3,2) (1,3,5)
10    int edges[4][3] = {{1, 2, 1}, {3, 4, 1}, {2, 3, 2}, {1, 3, 5}};
11    int cost = 0, taken = 0;
12    for (int i = 0; i < 4; i++) {
13        int x = edges[i][0], y = edges[i][1], w = edges[i][2];
14        if (find(x) != find(y)) {
15            fa[find(x)] = find(y);
16            cost += w; taken++;
17        }
18    }
19    cout << cost << " " << taken;
20    return 0;
21}

单选题:程序输出是?(Kruskal 最小生成树的总权与边数)

(1 分)
第 68 题 K6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(1)] = find(2);
10    cout << (______ ? "SAME" : "DIFF");   // 判 1、2 同集合
11    return 0;
12}

单选题:横线处应填入?(使输出为 SAME

(1 分)
第 69 题 K7 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[7];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 6; i++) fa[i] = i;
09    // 边:(1,2) (2,3) (4,5) —— 3 个连通块 {1,2,3}、{4,5}、{6}
10    fa[find(1)] = find(2);
11    fa[find(2)] = find(3);
12    fa[find(4)] = find(5);
13    int blocks = 0;
14    for (int i = 1; i <= 6; i++) if (find(i) == i) blocks++;
15    cout << blocks;
16    return 0;
17}

单选题:程序输出是?

(1 分)
拾贰

Trie 代码

6 QUESTIONS · 2 POINTS EACH
第 70 题 L1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];    // 子节点(0 = 空)
04int cnt[100];       // 经过次数
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;   // 新建节点
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int main() {
16    ins("cat"); ins("car"); ins("dog");
17    cout << tot;
18    return 0;
19}

单选题:程序输出是?(cat 新建 3 节点、car 新建 1 节点(r)、dog 新建 3 节点)

(1 分)
第 71 题 L2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int main() {
16    ins("cat"); ins("car");
17    cout << cnt[ch[0]['c' - 'a']];   // 根下 'c' 节点的经过次数
18    return 0;
19}

单选题:程序输出是?(以 'c' 开头的单词数)

(1 分)
第 72 题 L3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12    }
13    isEnd[p] = true;
14}
15bool query(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return false;
20        p = ch[p][t];
21    }
22    return isEnd[p];
23}
24int main() {
25    ins("cat"); ins("car"); ins("dog");
26    cout << (query("cat") ? "Y" : "N") << (query("ca") ? "Y" : "N")
27         << (query("cow") ? "Y" : "N");
28    return 0;
29}

单选题:程序输出是?(cat 存在、ca 不是完整单词、cow 不存在)

(1 分)
第 73 题 L4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int pref(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return 0;
20        p = ch[p][t];
21    }
22    return cnt[p];
23}
24int main() {
25    ins("cat"); ins("car"); ins("dog"); ins("do");
26    cout << pref("do");
27    return 0;
28}

单选题:程序输出是?(以 "do" 为前缀的单词数:dog、do 共 2 个)

(1 分)
第 74 题 L5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        ______;                  // 移动到子节点
12        cnt[p]++;
13    }
14}
15int main() {
16    ins("ab");
17    cout << tot;
18    return 0;
19}

单选题:横线处应填入?(使输出为 2

(1 分)
第 75 题 L6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12    }
13    isEnd[p] = true;
14}
15bool query(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return false;
20        p = ch[p][t];
21    }
22    return isEnd[p];
23}
24int main() {
25    ins("a"); ins("ab"); ins("abc");
26    cout << (query("a") ? "Y" : "N") << (query("ab") ? "Y" : "N")
27         << (query("abc") ? "Y" : "N") << (query("abcd") ? "Y" : "N");
28    return 0;
29}

单选题:程序输出是?

(1 分)
拾叁

Trie 应用代码

6 QUESTIONS · 2 POINTS EACH
第 76 题 M1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12    }
13    isEnd[p] = true;
14}
15bool query(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return false;
20        p = ch[p][t];
21    }
22    return isEnd[p];
23}
24int main() {
25    string words[4] = {"the", "a", "there", "answer"};
26    for (string w : words) ins(w);
27    cout << (query("there") ? "FOUND" : "NOT-FOUND");
28    return 0;
29}

单选题:程序输出是?

(1 分)
第 77 题 M2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int pref(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return 0;
20        p = ch[p][t];
21    }
22    return cnt[p];
23}
24int main() {
25    string words[5] = {"app", "apple", "apply", "banana", "apex"};
26    for (string w : words) ins(w);
27    cout << pref("app");
28    return 0;
29}

单选题:程序输出是?(以 "app" 为前缀的单词数:app、apple、apply 共 3 个)

(1 分)
第 78 题 M3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    // 最大异或对:对每个数在 01-Trie 上贪心走"相反位"路径
05    int a[3] = {3, 5, 6};
06    int mx = 0;
07    for (int i = 0; i < 3; i++)
08        for (int j = i + 1; j < 3; j++)
09            mx = max(mx, a[i] ^ a[j]);
10    cout << mx;
11    return 0;
12}

单选题:程序输出是?(3^5=6、3^6=5、5^6=3,最大 6)

(1 分)
第 79 题 M4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    string words[3] = {"banana", "apple", "apricot"};
05    sort(words, words + 3);
06    for (string w : words) cout << w << " ";
07    return 0;
08}

单选题:程序输出是?(字典序——Trie 深度优先遍历天然得到此序)

(1 分)
第 80 题 M5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12    }
13    ______;                  // 标记单词结束
14}
15int main() {
16    ins("hi");
17    cout << isEnd[2];
18    return 0;
19}

单选题:横线处应填入?(使输出为 1

(1 分)
第 81 题 M6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int main() {
16    string words[4] = {"ab", "abc", "abd", "ac"};
17    for (string w : words) ins(w);
18    // 统计以 'a' 开头的单词数 = 根下 'a' 节点的 cnt
19    cout << cnt[ch[0]['a' - 'a']];
20    return 0;
21}

单选题:程序输出是?

(1 分)
拾肆

综合代码

6 QUESTIONS · 2 POINTS EACH
第 82 题 N1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[5];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 4; i++) fa[i] = i;
09    // 四边形加一条对角线:(1,2) (2,3) (3,4) (4,1) —— 第 4 条边成环
10    int e[4][2] = {{1, 2}, {2, 3}, {3, 4}, {4, 1}};
11    int cycleAt = 0;
12    for (int i = 0; i < 4; i++) {
13        int x = e[i][0], y = e[i][1];
14        if (find(x) == find(y)) { cycleAt = i + 1; break; }
15        fa[find(x)] = find(y);
16    }
17    cout << cycleAt;
18    return 0;
19}

单选题:程序输出是?(第几条边发现成环)

(1 分)
第 83 题 N2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        cnt[p]++;
13    }
14}
15int main() {
16    ins("abc"); ins("abc"); ins("abd");
17    cout << cnt[ch[ch[ch[0]['a' - 'a']]['b' - 'a']]['c' - 'a']];
18    return 0;
19}

单选题:程序输出是?("abc" 路径末端节点的经过次数)

(1 分)
第 84 题 N3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[9];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 8; i++) fa[i] = i;
09    // 4 条边连成两个块:{1,2,3,4} 与 {5,6,7,8}
10    int e[4][2] = {{1, 2}, {2, 3}, {3, 4}, {5, 6}};
11    for (int i = 0; i < 4; i++) fa[find(e[i][0])] = find(e[i][1]);
12    int blocks = 0;
13    for (int i = 1; i <= 8; i++) if (find(i) == i) blocks++;
14    cout << blocks;
15    return 0;
16}

单选题:程序输出是?({1,2,3,4}、{5,6}、{7}、{8} 共 4 块)

(1 分)
第 85 题 N4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    // 朋友关系:1-2、3-4、4-5
10    fa[find(1)] = find(2);
11    fa[find(3)] = find(4);
12    fa[find(4)] = find(5);
13    cout << (find(2) == find(5) ? "CONNECTED" : "NOT-CONNECTED");
14    return 0;
15}

单选题:程序输出是?

(1 分)
第 86 题 N5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) ______;   // 初始化
09    cout << find(5);
10    return 0;
11}

单选题:横线处应填入?(使输出为 5

(1 分)
第 87 题 N6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[7], rk[7];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07void uni(int x, int y) {
08    int rx = find(x), ry = find(y);
09    if (rx == ry) return;
10    if (rk[rx] < rk[ry]) fa[rx] = ry;
11    else if (rk[rx] > rk[ry]) fa[ry] = rx;
12    else { fa[rx] = ry; rk[ry]++; }
13}
14int main() {
15    for (int i = 1; i <= 6; i++) { fa[i] = i; rk[i] = 0; }
16    uni(1, 2); uni(3, 4); uni(5, 6);   // 3 块
17    uni(2, 4);                          // 合并两块 → 2 块
18    cout << (find(1) == find(3) ? "S" : "D") << " ";
19    int blocks = 0;
20    for (int i = 1; i <= 6; i++) if (find(i) == i) blocks++;
21    cout << blocks;
22    return 0;
23}

单选题:程序输出是?

(1 分)
拾伍

完善程序

7 QUESTIONS · 2 POINTS EACH
第 88 题 O1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    if (______) return x;             // x 是根
06    return fa[x] = find(fa[x]);
07}
08int main() {
09    find(1);
10    cout << fa[1];
11    return 0;
12}

单选题:横线处应填入?(使输出为 5

(1 分)
第 89 题 O2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    ______;                      // union(2, 5)
10    cout << find(2) << " " << find(5);
11    return 0;
12}

单选题:横线处应填入?(使输出为 5 5

(1 分)
第 90 题 O3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    if (fa[x] == x) return x;
06    return fa[x] = ______;        // 递归找根并压缩
07}
08int main() {
09    find(1);
10    cout << fa[1] << " " << fa[2];
11    return 0;
12}

单选题:横线处应填入?(使输出为 5 5

(1 分)
第 91 题 O4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6], rk[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07void uni(int x, int y) {
08    int rx = find(x), ry = find(y);
09    if (rx == ry) return;
10    if (rk[rx] < rk[ry]) fa[rx] = ry;
11    else {
12        fa[ry] = rx;
13        if (______) rk[rx]++;       // 秩相等时根秩 +1
14    }
15}
16int main() {
17    for (int i = 1; i <= 4; i++) { fa[i] = i; rk[i] = 0; }
18    uni(1, 2); uni(3, 4); uni(1, 3);
19    cout << find(1);
20    return 0;
21}

单选题:横线处应填入?(使输出为 4——两树等高时合并、根的秩 +1)

(1 分)
第 92 题 O5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (______) ch[p][t] = ++tot;    // 边不存在则新建
11        p = ch[p][t];
12    }
13    isEnd[p] = true;
14}
15int main() {
16    ins("ab"); ins("ac");
17    cout << tot;
18    return 0;
19}

单选题:横线处应填入?(使输出为 3——a、b、c 三个节点)

(1 分)
第 93 题 O6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04bool isEnd[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12    }
13    isEnd[p] = true;
14}
15bool query(string s) {
16    int p = 0;
17    for (char c : s) {
18        int t = c - 'a';
19        if (!ch[p][t]) return false;
20        p = ch[p][t];
21    }
22    return ______;               // 完整单词需结束标记
23}
24int main() {
25    ins("ab");
26    cout << (query("ab") ? "Y" : "N") << (query("a") ? "Y" : "N");
27    return 0;
28}

单选题:横线处应填入?(使输出为 YN

(1 分)
第 94 题 O7 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(1)] = find(2);
10    fa[find(3)] = find(4);
11    cout << (find(1) == find(4) ? "S" : "D") << " ";
12    fa[find(2)] = find(3);       // 合并两集合
13    cout << (find(1) == find(4) ? ______ : "D");
14    return 0;
15}

单选题:横线处应填入?(使输出为 D S

(1 分)
拾陆

代码易错

6 QUESTIONS · 2 POINTS EACH
第 95 题 P1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6] = {0, 2, 3, 4, 5, 5};
04int find(int x) {
05    while (fa[x] != x) x = fa[x];   // 无路径压缩
06    return x;
07}
08int main() {
09    int total = 0;
10    for (int i = 1; i <= 5; i++) {
11        int x = i, steps = 0;
12        while (fa[x] != x) { x = fa[x]; steps++; }
13        total += steps;
14    }
15    cout << total;
16    return 0;
17}

单选题:程序输出是?(链 1→2→3→4→5 上 5 次 find 的总步数 = 4+3+2+1+0)

(1 分)
第 96 题 P2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];                        // 未初始化!
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    // 未初始化 fa[i] = i 直接 find——fa 全是 0,find(1) 会走 fa[1]=0 → find(0) 越界
09    cout << "danger";
10    return 0;
11}

判断题:并查集未初始化 fa[i] = i 就 find,会沿 0 下标越界递归——初始化是并查集的第一步。

(1 分)
第 97 题 P3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int fa[6];
04int find(int x) {
05    return fa[x] == x ? x : fa[x] = find(fa[x]);
06}
07int main() {
08    for (int i = 1; i <= 5; i++) fa[i] = i;
09    fa[find(2)] = find(2);     // union(2, 2):自己挂自己
10    cout << find(2) << " ";
11    // 正确写法:if (find(x) == find(y)) return; 提前返回
12    cout << "ok";
13    return 0;
14}

单选题:程序输出是?(自环 union 后 find(2) 的结果)

(1 分)
第 98 题 P4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];     // 0 表示空
04int tot = 0;
05int main() {
06    // 错误示范:把节点 0(根)当作"空"判断——根也是 0,与新节点混淆
07    // 正确:tot 从 0 开始,新建节点 ++tot(从 1 开始编号),0 永远是根
08    cout << "root is 0";
09    return 0;
10}

判断题:Trie 中根节点固定为 0、新节点从 1 开始编号——若新建节点也从 0 编号会与根冲突。

(1 分)
第 99 题 P5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int ch[100][26];
04int cnt[100];
05int tot = 0;
06void ins(string s) {
07    int p = 0;
08    for (char c : s) {
09        int t = c - 'a';
10        if (!ch[p][t]) ch[p][t] = ++tot;
11        p = ch[p][t];
12        // 错误:忘了 cnt[p]++ —— 前缀统计全为 0
13    }
14}
15int main() {
16    ins("ab"); ins("ac");
17    cout << cnt[ch[0]['a' - 'a']];
18    return 0;
19}

单选题:程序输出是?(忘计数后前缀统计失效)

(1 分)
第 100 题 P6 未作答

判断题:以下结论全部正确——"并查集初始化 fa[i]=i;find 带路径压缩;union 按秩防退化;Trie 根为 0、新节点从 1 编号;前缀查询无需结束标记"。

(1 分)