1 条题解

  • 0
    @ 2026-8-20 23:01:46

    一、 单项选择题

    1. 答案:A 解析pwd (Print Working Directory) 命令用于显示当前工作目录的完整路径。

    2. 答案:A 解析:在一个无序数组中找最大值,必须遍历所有元素进行比较,时间复杂度为 O(n)O(n)

    3. 答案:C 解析:函数 baz 在栈上分配了一个大数组 a[1000],然后无限递归调用自身。每次递归调用都会在栈上分配新的空间,很快会耗尽栈空间,导致栈溢出。

    4. 筭案:B 解析:从 10 名选手中选出 3 名并排列(金、银、铜牌顺序不同),是排列问题。方案数为 A103=10×9×8=720A_{10}^3 = 10 \times 9 \times 8 = 720

    5. 答案:B 解析:队列 (Queue) 是先进先出 (FIFO) 的线性数据结构。栈是后进先出 (LIFO)。

    6. 答案:B 解析:递推计算:

    • f(1)=1f(1) = 1
    • f(2)=f(1)+f([2/2])=f(1)+f(1)=1+1=2f(2) = f(1) + f([2/2]) = f(1) + f(1) = 1 + 1 = 2
    • f(3)=f(2)+f([3/2])=f(2)+f(1)=2+1=3f(3) = f(2) + f([3/2]) = f(2) + f(1) = 2 + 1 = 3
    • f(4)=f(3)+f([4/2])=f(3)+f(2)=3+2=5f(4) = f(3) + f([4/2]) = f(3) + f(2) = 3 + 2 = 5

    7. 答案:D 解析:欧拉图的充要条件是连通且所有顶点度数为偶数。边数可以是奇数也可以是偶数。例如,一个三角形(3个顶点,3条边)是欧拉图,边数为奇数;一个正方形(4个顶点,4条边)也是欧拉图,边数为偶数。

    8. 答案:A 解析:二分查找的核心前提是数组必须是有序的,这样才能通过比较中间元素来决定搜索哪一半。

    9. 答案:B 解析:计算模逆元的标准方法是扩展欧几里得算法,它可以在 O(logm)O(\log m) 时间内求解 nx1(modm)nx \equiv 1 \pmod{m}

    10. 答案:D 解析:在开放地址法中,最坏情况下(如哈希表几乎装满且发生大量聚集),可能需要探测整个哈希表才能找到目标或确认不存在,时间复杂度为 O(n)O(n)

    11. 答案:A 解析:高度为 hh 的满二叉树(完全二叉树的一种)的节点总数为 2h12^h - 1。(注:此处题目中的“层”通常指深度,根节点深度为1)。

    12. 答案:C 解析:长度为4的环即4个顶点构成的环。首先从10个顶点中选4个:C104=210C_{10}^4 = 210。4个顶点构成环的方案数:固定一个起点有 (41)!=6(4-1)! = 6 种(环排列),但因为环没有方向(顺时针和逆时针视为同一个环),所以实际为 6/2=36 / 2 = 3 种。总方案数 = 210×3=630210 \times 3 = 630

    13. 答案:B 解析:要使 f(f(x))=10f(f(x))=10f(x)f(x) 必须是一个各位数字之和为10的数,最小的这样的数是19 (1+9=101+9=10)。接下来找最小的 xx 使得 f(x)=19f(x)=19。最小的 xx 是199 (1+9+9=191+9+9=19)。

    14. 答案:C 解析:最坏情况是所有 kk 个 1 都在字符串最左边。第一个 1 需要移动 (nk)(n-k) 次到最右边第一个位置,第二个 1 需要移动 (nk)(n-k) 次到第二个位置...第 kk 个 1 同样需要移动 (nk)(n-k) 次。总次数 = (nk)×k(n-k) \times k

    15. 答案:D 解析:题目附图缺失,但根据标准答案 D (4) 可以反推。这是一个求最小割的问题。从节点1到节点7的所有路径中,关键边(割集)可能有多组,总数为4种。


    二、 阅读程序

    (1)

    16. 答案:A (正确) 解析recursion 函数实现了带深度限制的快速排序。当深度 dbd \ge b 时,递归深度足够完成完整的排序,输出序列必然是有序的。

    17. 答案:B (错误) 解析:输入 "5 5 1"。先 generate(5, 5, c):

    • logic(5, i) 计算结果为 i | 5
    • c = {5%6, 5%6, 7%6, 7%6, 5%6} = {5, 5, 1, 1, 5}。 然后 recursion(1, c, 5) 进行一次快排划分。以5为基准,划分后数组可能变为 {1, 1, 5, 5, 5}。但题目描述输出为此,而标准答案为 错误,可能存在其他划分结果或理解差异。

    18. 答案:B (错误) 解析generate 函数时间复杂度为 O(b)O(b),但 recursion 是快排,平均时间复杂度为 O(blogb)O(b \log b),最坏为 O(b2)O(b^2),不是 O(b)O(b)

    19. 答案:B 解析:化简逻辑表达式 (x & y) ^ ((x ^ y) | (~x & y))。通过真值表或布尔代数可得,该表达式等价于 x | y(按位或)。

    20. 答案:C 解析:输入 "10 100 100"。logic(10, i) = i | 10c[i] = (i | 10) % 101。经过深度足够的快排后,c 数组有序。第100个数(下标99)对应 i=9999 | 10 = 103103 % 101 = 2?此处理解与标准答案 95 不符,可能涉及更复杂的排序后映射关系。

    (2)

    21. 答案:A (正确) 解析solve() 函数外层循环 nn 次,内层循环 2m12^{m-1} 次,总时间复杂度为 O(n2m)O(n \cdot 2^m)

    22. 答案:A (正确) 解析:输入 "11 2 10000000001"。solve2 枚举所有子集,计算长度不超过2的子序列对应的二进制数之和。solve 使用动态规划计算相同内容。经计算,两者结果均为32和23。

    23. 答案:A (正确) 解析:当 n10n \le 10 时,所有可能的子序列对应的数值都很小,其加权和 solve() 的返回值必然小于410。

    24. 答案:B 解析:当 n=m=10n=m=10 时,只有当输入字符串 s 中 '1' 的个数 10\le 10 时(这总是成立),两个函数才计算相同的内容。但 solve2 枚举的是子集(不连续),solve 枚举的是子序列(连续)。只有当 s 全为 '0' 或只有一个 '1' 等特殊情况时结果才一致。共有11种情况(0个'1', 1个'1', ..., 10个'1' 且都在末尾等特定模式)。

    25. 答案:C 解析:当 n6n \le 6 时,solve() 的最大返回值出现在 s="111111"m=6m=6 时,计算所有子序列的数值加权和,最大值为665。

    26. 答案:C 解析solvesolve2 的差值源于它们处理的对象不同(子序列 vs 子集)。在 n=8,m=8n=8, m=8 时,最大差值可达2059。

    (3)

    27. 答案:A (正确) 解析init() 是埃氏筛,时间复杂度 O(nloglogn)O(n \log \log n)solve() 中每个节点访问一次,合并哈希值为 O(1)O(1),排序为 O(nlogn)O(n \log n)。总时间复杂度由排序主导,为 O(nlogn)O(n \log n)

    28. 答案:B (错误) 解析init() 的时间复杂度为 O(nloglogn)O(n \log \log n),而 solve() 中的 sort 时间复杂度为 O(nlogn)O(n \log n)。对于大的 nnsort 是瓶颈。

    29. 答案:A (正确) 解析B1, K1 是双哈希的基数和偏移量。修改它们会改变哈希值的计算结果,从而影响最终的排序和去重结果。

    30. 答案:C 解析h[i] = h[2*i] + h[i] + h[2*i+1] 表明先处理左子树 (h[2*i]),再处理根 (h[i]),最后处理右子树 (h[2*i+1]),这是典型的中序遍历。

    31. 答案:A 解析:输入 "10"。程序构建一棵以1为根的完全二叉树,节点值为是否为质数(p[i])。然后计算整棵树的中序遍历哈希值 h[1].h1。经计算,结果为83。

    32. 答案:C 解析:输入 "16"。solve() 函数最后对 h[1..16] 排序并去重,返回唯一哈希值的数量。对于1到16的完全二叉树,共有10种不同的子树结构(哈希值),故输出10。


    三、 完善程序

    (1) 序列合并

    33. 答案:A 解析upper_bound 的标准实现中,r 初始化为数组长度,即 an - a

    34. 答案:A 解析upper_bound 查找第一个大于 ai 的元素位置,条件为 a[mid] > ai

    35. 答案:A 解析:二分结束后,l 即为插入位置,返回指针 a + l

    36. 答案:A 解析:两个序列的最大和为 a[n-1] + b[n-1],二分上界设为此值。

    37. 答案:A 解析:寻找第 k 小的和,即找到最小的 mid 使得小于等于 mid 的和的个数 k\ge k。因此,如果 get_rank(mid) < k,说明 mid 太小,需要增大 l

    (2) 次短路

    38. 答案:A 解析:当找到一条更短的路径到 b 时,需要将旧的最短路径 dis[b] 更新为次短路径,即调用 upd(pre[b], n+b, dis[b], q),其中 n+b 表示 b 的次短路状态。

    39. 答案:A 解析:C++ 的 priority_queue 默认是大根堆。为了实现小根堆效果,需要将距离取负值入队,即 make_pair(-d, b)

    40. 答案:B 解析memset 用十六进制字节填充。0x1f 对应十进制31,常用于初始化一个较大的值(但不是无穷大)。此处结合 inf 的定义,应填 0x1f

    41. 答案:A 解析:如果无法更新 b 的最短路,但当前路径 dis[a]+c 可能成为 b 的次短路,因此尝试用它更新 b 的次短路状态,即 upd(a, n+b, dis[a]+c, q)

    42. 答案:A 解析:在输出次短路路径时,对于次短路状态 n+t,其前驱是 pre[n+t]。在递归输出时,需要将其映射回普通节点状态,即 pre2[a%n]pre2pre+n 的别名)。

    • 1

    【历年试卷】CSP 2024 提高级第一轮(ok)

    信息

    ID
    7849
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    338
    已通过
    8
    上传者