CSP-J1 2019
T1
中国的国家顶级域名是
- A. cn
- B. ch
- C. chn
- D. china
答案
A
域名级数是指一个域名由多少级组成,域名的各个级别被“.”分开,最右边的为顶级域名。顶级域名,又称一级域名,常见的有“.com”、“.org”、“.net”、“.cn”等,二级域名就是在一级域名前再加一级,如“baidu.com”。
T2
二进制数 11101110010111 和 01011011101011 进行按位与运算的结果是
- A. 01001010001011
- B. 01001010010011
- C. 01001010000001
- D. 01001010000011
答案
D
T3
一个 32 位整型变量占用多少个字节
- A. 32
- B. 128
- C. 4
- D. 8
答案
C
1 个字节是 8 位二进制
T4
若有如下程序段,其中 s、a、b、c 均为已定义的整型变量,且 a、c 均已赋值(c 大于 0)
s = a; for (b = 1; b <= c; b++) s = s - 1;
则与上述程序段功能等价的赋值语句是
- A.
s = a - c;
- B.
s = a - b;
- C.
s = s - c;
- D.
s = b - c;
答案
A
T5
设有 100 个已排好序的数据元素,采用折半查找时,最大比较次数为
- A. 7
- B. 10
- C. 6
- D. 8
答案
A
T6
链表不具有的特点是
- A. 插入删除不需要移动元素
- B. 不必事先估计存储空间
- C. 所需空间与线性表长度成正比
- D. 可随机访问任一元素
答案
D
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。由于不必须按顺序存储,链表在插入的时候可以达到 O(1) 的复杂度,但是查找一个结点或者访问特定编号的结点则需要 O(n) 的时间。
使用链表结构可以克服数组需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
T7
把 8 个同样的球放在 5 个同样的袋子里,允许有的袋子空着不放,问共有多少种不同的分法?
提示:如果 8 个球都放在一个袋子里,无论是哪个袋子,都只算同一种分法。
- A. 22
- B. 24
- C. 18
- D. 20
答案
C
4 个空袋:8
3 个空袋:1+7,2+6,3+5,4+4
2 个空袋:1+1+6,1+2+5,1+3+4,2+2+4,2+3+3
1 个空袋:1+1+1+5,1+1+2+4,1+1+3+3,1+2+2+3,2+2+2+2
没有空袋:1+1+1+1+4,1+1+1+2+3,1+1+2+2+2
T8
一棵二叉树如图所示,若采用顺序存储结构,即用一维数组元素存储该二叉树中的结点(根结点的下标为 1,若某结点的下标为 i,则其左孩子位于下标 2i 处,右孩子位于下标 2i+1 处),则该数组的最大下标至少为
- A. 6
- B. 10
- C. 15
- D. 12
答案
C
T9
100 以内最大的素数是
- A. 89
- B. 97
- C. 91
- D. 93
答案
B
T10
319 和 377 的最大公约数是
- A. 27
- B. 33
- C. 29
- D. 31
答案
C
T11
新学期开学了,小胖想减肥,健身教练给小胖制定了两个训练方案。
方案一:每次连续跑 3 公里可以消耗 300 千卡(耗时半小时);
方案二:每次连续跑 5 公里可以消耗 600 千卡(耗时 1 小时)。
小胖每周一到周四能抽出半小时跑步,周五到周日能抽出一小时跑步。另外,教练建议小胖每周最多跑 21 公里,否则会损伤膝盖。
请问如果小胖想严格执行教练的训练方案,并且不想损伤膝盖,每周最多通过跑步消耗多少千卡?
- A. 3000
- B. 2500
- C. 2400
- D. 2520
答案
C
跑 3 个 1 小时和 2 个半小时,总计 21 公里,2400 千卡热量
T12
一副纸牌除掉大小王有 52 张牌,四种花色,每种花色 13 张。假设从这 52 张牌中随机抽取 13 张纸牌,则至少多少张牌的花色一致
- A. 4
- B. 2
- C. 3
- D. 5
答案
A
抽屉原理:13 张,4 种花色,3 套 4 种花色再加 1 张
T13
一些数字可以颠倒过来看,例如 0、1、8 颠倒过来还是本身,6 颠倒过来是 9,9 颠倒过来看还是 6,其他数字颠倒过来都不构成数字。
类似地,一些多位数也可以颠倒过来看,比如 106 颠倒过来是 901,假设某个城市的车牌只由 5 位数字组成,每一位都可以取到 0 到 9,请问这个城市最多有多少个车牌倒过来恰好还是原来的车牌?
- A. 60
- B. 125
- C. 75
- D. 100
答案
C
第 1、2 位有(0、1、8、6、9)五个数字,第 3 位有(0、1、8)三个数字,第 4、5 位由第 1、2 位决定(如第 1 位 6,则第 5 位 9),5*5*3=75
T14
假设一棵二叉树的后序遍历序列为 DGJHEBIFCA,中序遍历序列为 DBGEHJACIF,则其前序遍历序列为
- A. ABDCEFGHIJ
- B. ABDEGHJCFI
- C. ABDEGJHCFI
- D. ABDEGHJFIC
答案
B
相关习题:P1030 求先序排列
T15
以下哪个奖项是计算机科学领域的最高奖?
- A. 图灵奖
- B. 鲁班奖
- C. 诺贝尔奖
- D. 普利策奖
答案
A
T16
#include <cstdio> #include <cstring> using namespace std; char st[100]; int main() { scanf("%s", st); int n = strlen(st); for (int i = 1; i <= n; i++) { if (n % i == 0) { char c = st[i - 1]; if (c >= 'a') st[i - 1] = c - 'a' + 'A'; } } printf("%s", st); return 0; }
程序分析
输入一个字符串,对于序号是 n 的约数的字符,ASCII 码减 32(如果原本是小写字母,会转成大写字母)
1. 输入的字符串只能由小写字母或大写字母组成。
答案
错误
2. 若将第 8 行的i = 1
改为i = 0
,程序运行时会发生错误。
答案
正确
除法的除数为 0,会产生浮点数错误
3. 若将第 8 行的i <= n
改为i * i <= n
,程序运行结果不会改变。
答案
错误
假设 n=16,修改后,i=8 不会被处理
4. 若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。
答案
正确
5. 若输入的字符串长度为 18,那么输入的字符串跟输出的字符串相比,至多有多少个字符不同
- A. 18
- B. 6
- C. 10
- D. 1
答案
B
i=1,2,3,6,9,18
6. 若输入的字符串长度为多少,那么输入的字符串跟输出的字符串相比,至多有 36 个字符不同
- A. 36
- B. 100000
- C. 1
- D. 128
答案
B
计算幂次,则 2 有 0-5 一共 6 种取法,5 有 0-5 一共 6 种取法,6×6=36
T17
#include <cstdio> using namespace std; int n, m; int a[100], b[100]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) a[i] = b[i] = 0; for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); if (a[x] < y && b[y] < x) { if (a[x] > 0) b[a[x]] = 0; if (b[y] > 0) a[b[y]] = 0; a[x] = y; b[y] = x; } } int ans = 0; for (int i = 1; i <= n; ++i) { if (a[i] == 0) ++ans; if (b[i] == 0) ++ans; } printf("%d\n", ans); return 0; }
假设输入的 n 和 m 都是正整数,x 和 y 都是在 [1,n] 的范围内的整数
程序分析
有 a、b 两组元素,两组元素之间相互两两对应。初始时所有元素都和另一组的 0 对应。
每次考察 a 组的第 x 个元素和 b 组的第 y 个元素,如果新的配对方案使与 a[x] 和 b[y] 配对的两个端点都向右移动(这两个元素之前的配对交叉了),就重新配对。蓝线为新配对方案,红线为原配对方案。
最后输出未配对元素数量。
1. 当 m>0 时,输出的值一定小于 2n
答案
正确
至少会有一对配对成功
2. 执行完第 27 行的++ans
时,ans 一定是偶数
答案
错误
本题相当于两个数组间有若干条线有对照关系,最终的 ans 必定为偶数,但是在 for 循环的统计过程中不一定。如当 i=1 时,执行完第 27 行,ans 是奇数
3. a[i] 和 b[i] 不可能同时大于 0
答案
错误
令 m=1,输入 x=2,y=2 时,a[i] 和 b[i] 同时为 2
4. 若程序执行到第 13 行时,x 总是小于 y,那么第 15 行不会被执行
答案
错误
如果 x 之前已经配对过,则会更新,如:(1,2)、(1,3)
5. 若 m 个 x 两两不同,且 m 个 y 两两不同,则输出的值为
- A. 2n-2m
- B. 2n+2
- C. 2n-2
- D. 2n
答案
A
因为 m 个 x 和 m 个 y 互不相同,会成功配对 m 次(配对前各自初始值为 0,配对后不会更新)。m 次循环中会有 2m 个位置的值发生变化,ans=2n-2m
6. 若 m 个 x 两两不同,且 m 个 y 都相等,则输出的值为
- A. 2n-2
- B. 2n
- C. 2m
- D. 2n-2m
答案
A
x 和 y 配对时每次都会清理掉之前的配对(或者不更新配对),最终只会产生一组配对,所以和 0 配对的元素数量为 2n-2
T18
#include <iostream> using namespace std; const int maxn = 10000; int n; int a[maxn]; int b[maxn]; int f(int l, int r, int depth) { if (l > r) return 0; int min = maxn, mink; for (int i = l; i <= r; ++i) { if (min > a[i]) { min = a[i]; mink = i; } } int lres = f(l, mink - 1, depth + 1); int rres = f(mink + 1, r, depth + 1); return lres + rres + depth * b[mink]; } int main() { cin >> n; for (int i = 0; i < n; ++i) cin >> a[i]; for (int i = 0; i < n; ++i) cin >> b[i]; cout << f(0, n - 1, 1) << endl; return 0; }
程序分析
将数组 b 根据数组 a 的值构造成一棵二叉树,二叉树的节点是 b 数组的元素。每次在序列 a 中选择值最小且靠前的元素作为根,根左侧的序列构建左子树,根右侧的序列构建右子树,递归求解。最后求每个节点值 b[i] 乘深度 depth 的和。
1. 如果 a 数组有重复的数字,则程序运行时会发生错误
答案
错误
每次是找第一次出现的最小值,重复不影响
2. 如果 b 数组全为 0,则输出为 0
答案
正确
ans 是求每个节点值 b[i] 乘深度 depth 的和
3. 当 n=100 时,最坏情况下,与第 12 行的比较运算执行次数最接近的是
- A. 5000
- B. 600
- C. 6
- D. 100
答案
A
最坏情况为每次的 min 都在最左或最右,一次只能构建单侧子树,每层只少一个点。则总比较次数为 100+99+98+......+1=5050
4. 当 n=100 时,最好情况下,与第 12 行的比较运算执行次数最接近的是
- A. 100
- B. 6
- C. 5000
- D. 600
答案
D
最好情况是每次 min 都在序列中间,刚好平分两个子树,则深度大约为
5. 当 n=10 时,若 b 数组满足,对任意 0<=i<n,都有 b[i]=i+1,那么输出最大为
- A. 386
- B. 383
- C. 384
- D. 385
答案
D
最大值为权值最大的深度最深,结果为 10*10+9*9+8*8+......+2*2+1*1=385
6. 当 n=100 时,若 b 数组满足,对任意 0<=i<n,都有 b[i]=1,那么输出最小为
- A. 582
- B. 580
- C. 579
- D. 581
答案
B
即构造一个 100 节点的二叉树,想要值最小则尽可能形成完全二叉树
1*1+2*2+4*3+8*4+16*5+32*6+37*7=580
T19
(矩阵变幻)有一个奇幻的矩阵,在不停地变幻,其变幻方式为:数字 0 变成矩阵
例如,矩阵最初为:
输入一行一个不超过 10 的正整数 n,输出变幻 n 次后的矩阵,试补全程序
提示:“<<”表示二进制左移运算符,例如
#include <cstdio> using namespace std; int n; const int max_size = 1 << 10; int res[max_size][max_size]; void recursive(int x, int y, int n, int t) { if (n == 0) { res[x][y] = _____(1)_____; return; } int step = 1 << (n - 1); recursive(_____(2)_____, n - 1, t); recursive(x, y + step, n - 1, t); recursive(x + step, y, n - 1, t); recursive(_____(3)_____, n - 1, !t); } int main() { scanf("%d", &n); recursive(0, 0, _____(4)_____); int size = _____(5)_____; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) printf("%d", res[i][j]); puts(""); } return 0; }
1. ①处应填
- A.
n % 2
- B.
0
- C.
t
- D.
1
答案
C
res[x][y] 仅有这处赋值,从题意和递归调用时 t 的赋值可知为 t
2. ②处应填
- A.
x - step, y - step
- B.
x, y - step
- C.
x - step, y
- D.
x, y
答案
D
四次递归调用代表一个数扩充为 4 个,x、y 是其坐标,②处为左上,坐标不变
3. ③处应填
- A.
x - step, y - step
- B.
x + step, y + step
- C.
x - step, y
- D.
x, y - step
答案
B
四次递归调用代表一个数扩充为 4 个,x、y 是其坐标,③处为右下,x、y 均增加
4. ④处应填
- A.
n - 1, n % 2
- B.
n, 0
- C.
n, n % 2
- D.
n - 1, 0
答案
B
第一次调用 recursive 函数,n 是矩阵规模,初始为 n,t 是 0 或 1,初始为 0
第一个空处递归函数返回点是 n==0,每次递归 n-1,第二个空处递归函数每次前三个是 t,则主函数第一次调用是 0
5. ⑤处应填
- A.
1 << (n + 1)
- B.
1 << n
- C.
n + 1
- D.
1 << (n - 1)
答案
B
size 是输出矩阵的边长,
T20
(计数排序)计数排序是一个广泛使用的排序方法。下面的程序使用双关键字计数排序,将 n 对 10000 以内的整数,从小到大排序,试补全程序
例如有三对整数 (3,4)、(2,4)、(3,3),那么排序之后应该是 (2,4)、(3,3)、(3,4)
输入第一行为 n,接下来 n 行,第 i 行有两个数 a[i] 和 b[i],分别表示第 i 对整数的第一关键字和第二关键字
从小到大排序后输出
数据范围:
提示:应先对第二关键字排序,再对第一关键字排序,数组 ord[] 存储第二关键字排序的结果,数组 res[] 存储双关键字排序的结果
#include <cstdio> #include <cstring> using namespace std; const int maxn = 10000000; const int maxs = 10000; int n; unsigned a[maxn], b[maxn],res[maxn], ord[maxn]; unsigned cnt[maxs + 1]; int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d%d", &a[i], &b[i]); memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; ++i) ①; // 利用 cnt 数组统计数量 for (int i = 0; i < maxs; ++i) cnt[i + 1] += cnt[i]; for (int i = 0; i < n; ++i) ②; // 记录初步排序结果 memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; ++i) ③; // 利用 cnt 数组统计数量 for (int i = 0; i < maxs; ++i) cnt[i + 1] += cnt[i]; for (int i = n - 1; i >= 0; --i) ④; // 记录最终排序结果 for (int i = 0; i < n; i++) printf("%d %d", ⑤); return 0; }
1. ①处应填
- A.
++cnt[i]
- B.
++cnt[b[i]]
- C.
++cnt[a[i] * maxs + b[i]]
- D.
++cnt[a[i]]
答案
B
先对第二关键字进行桶计数
2. ②处应填
- A.
ord[--cnt[a[i]]] = i
- B.
ord[--cnt[b[i]]] = a[i]
- C.
ord[--cnt[a[i]]] = b[i]
- D.
ord[--cnt[b[i]]] = i
答案
D
cnt[b[i]] 表示按第二关键字排序,第 i 个数排第几位,ord[x] 表示第二关键字排名第 x 的数在原序列的下标
3. ③处应填
- A.
++cnt[b[i]]
- B.
++cnt[a[i] * maxs + b[i]]
- C.
++cnt[a[i]]
- D.
++cnt[i]
答案
C
再对第一关键字进行桶计数
4. ④处应填
- A.
res[--cnt[a[ord[i]]]] = ord[i]
- B.
res[--cnt[b[ord[i]]]] = ord[i]
- C.
res[--cnt[b[i]]] = ord[i]
- D.
res[--cnt[a[i]]] = ord[i]
答案
A
统计出最后结果,res[x] 表示 a[] 为第一关键字,b[] 为第二关键字排序第 x 的数对在原序列的下标
5. ⑤处应填
- A.
a[i], b[i]
- B.
a[res[i]], b[res[i]]
- C.
a[ord[res[i]]], b[ord[res[i]]]
- D.
a[res[ord[i]]], b[res[ord[i]]]
答案
B
res[i] 记录第 i 个数在原序列的位置,且 a、b 数组内容必然成对输出,下标必须一致
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」