ARTICLE · 1047693
2026 CSP-J 第一轮真题及逐题详细解析

一、单项选择题(共15题,每题2分,共30分)
第1题
题干:下列C++ 数据类型中,能够精确存储 10^18+1 的是?
A. float B. long long C. double D. int
解析:
1. int为32位整型,最大值 \(2^{31}-1=2147483647\),远小于 \(10^{18}\),无法存储;
2. float/double为浮点数,存在精度限制:float有效精度24位二进制,double有效精度53位二进制,无法精确存储 \(10^{18}\) 附近的整数,末位会丢失;
3. long long为64位有符号整型,最大值 \(2^{63}-1\approx9\times10^{18}\),可完整精确存储 \(10^{18}+1\)。
答案:B
易错点:浮点数数值范围大,不代表可以精确存储所有大整数。
第2题
题干:十六进制数2F5转换为八进制数是?
A. 1364 B. 1635 C. 1405 D. 1365
解析:
十六进制转八进制核心:一位十六进制对应四位二进制,拼接后从右往左三位分组转八进制。
2→0010,F(15)→1111,5→0101,完整二进制:0010 1111 0101
从右三位分组:001 | 011 | 110 | 101,对应八进制:1、3、6、5,结果为1365。
十进制核验:\(2\times256+15\times16+5=757\),\(1\times512+3\times64+6\times8+5=757\)。
答案:D
易错点:F代表十进制15而非16;二进制分组必须从最低位开始。
第3题
题干:执行代码 `int a=7,b=3; cout<<a/b*b+a%b;` 输出为?
A. 9 B. 10 C. 7 D. 6
解析:
C++整型除法向下取整:\(7/3=2\),取余运算:\(7\%3=1\);
代入计算:\(2\times3+1=7\);
符合带余除法公式:被除数 = 商 × 除数 + 余数。
答案:C
易错点:整型除法无小数,不能按2.333计算。
第4题
题干:1、2、3、4依次入栈,随时可出栈,不可能的出栈序列是?
A. 2,4,3,1 B. 1,2,3,4 C. 3,1,2,4 D. 1,4,3,2
解析:
栈遵循后进先出规则:第一个出栈为3,说明必先压入1、2、3,此时栈内从底到顶为1、2;
3弹出后,栈顶为2,下一个只能弹出2,无法直接弹出栈底的1,因此C序列不成立。
答案:C
易错点:出栈自由但只能弹出栈顶元素,不能随机选取栈内元素。
第5题
题干:100个结点的完全二叉树,叶子结点个数为?
A. 49 B. 50 C. 64 D. 51
解析:
完全二叉树编号规则:结点i的左孩子为2i,若2i≤n则为非叶子结点;
100个结点中,1~50号结点均有孩子,为非叶子结点;51~100号共50个叶子结点;
通用公式:n个结点完全二叉树叶子数 = \(n-\lfloor n/2 \rfloor\)。
答案:B
易错点:完全二叉树≠满二叉树,最后一层不一定填满。
第6题
题干:统计1~100中3或5的倍数总和,求s的值?
A. 3048 B. 2733 C. 2318 D. 2418
解析:容斥原理,避免重复计算15的倍数
1. 3的倍数和:\(3\times(1+2+\dots+33)=1683\)
2. 5的倍数和:\(5\times(1+2+\dots+20)=1050\)
3. 15的重复倍数和:\(15\times(1+2+\dots+6)=315\)
4. 总和:\(1683+1050-315=2418\)
答案:D
易错点:直接累加两类倍数会重复计算公倍数。
第7题
题干:楼梯每次走1/2/3级,走到第8级的走法数?
A. 44 B. 121 C. 149 D. 81
解析:递推DP问题
状态方程:\(f(t)=f(t-1)+f(t-2)+f(t-3)\)(最后一步走1/2/3级)
初始状态:\(f(0)=1,f(1)=1,f(2)=2\)
递推计算:f(3)=4、f(4)=7、f(5)=13、f(6)=24、f(7)=44、f(8)=81
答案:D
易错点:1+2和2+1为不同走法,需统计有序路径。
第8题
题干:5×5网格BFS,E第一次入队时,累计入队格子数?
A. 15 B. 12 C. 14 D. 13
解析:
障碍坐标:(0,3)、(1,3)、(2,3)、(3,0)、(3,1)、(4,3),起点S(0,0),终点E(3,4)
按上下左右顺序入队,首次入队格子共14个,E入队时统计结束。
答案:C
易错点:统计所有入队过的格子,而非最短路径格子,也不等E出队再统计。
第9题
题干:1≤n≤100,满足gcd(n,60)=6的n有多少个?
A. 8 B. 6 C. 4 D. 5
解析:
令n=6k,则gcd(6k,60)=6×gcd(k,10),要求gcd(k,10)=1;
1≤n≤100 → 1≤k≤16,k需与10互质(非2、5倍数);
符合条件k:1、3、7、9、11、13,共6个,对应n:6、18、42、54、66、78。
答案:B
易错点:仅筛选6的倍数不够,需排除与60存在更大公因数的数。
第10题
题干:面值1、4、6元,凑9元最少硬币数?
A. 3 B. 4 C. 5 D. 2
解析:
贪心反例:优先选6元,剩余3元需3个1元,共4枚,非最优;
最优方案:4+4+1=9,仅需3枚,无法用2枚凑出9元。
答案:A
易错点:贪心算法不适用于所有币值系统,需全局最优判断。
第11题
题干:数组a[5]={1,3,5,7,9},指针运算后输出a[1],a[3]?
A. 14,13 B. 8,13 C. 14,7 D. 14,2
解析:
1. p=a+2,p指向a[2]=5,p[0]=5,p[2]=a[4]=9;
2. *(p-1)=a[1]=5+9=14,数组更新为{1,14,5,7,9};
3. p[1]=a[3]=*(a+1)-a[0]=14-1=13;
最终a[1]=14,a[3]=13。
答案:A
易错点:指针下标以p为起点,后续运算读取更新后的数组值。
第12题
题干:1000个元素升序数组,二分查找最坏比较次数?
A. 500 B. 9 C. 11 D. 10
解析:
二分查找最坏次数规律:k次最多覆盖 \(2^k-1\) 个元素;
\(2^9-1=511<1000\),\(2^{10}-1=1023≥1000\),故最坏需要10次。
答案:D
第13题
题干:前缀和s[i]=3i²+i,求a[10]?
A. 252 B. 310 C. 58 D. 61
解析:
单项公式:\(a[i]=s[i]-s[i-1]\)
s[10]=3×100+10=310,s[9]=3×81+9=252
a[10]=310-252=58
答案:C
第14题
题干:点坐标1、3、4、7、10、15、20,求距离和最小的最小值?
A. 37 B. 42 C. 40 D. 38
解析:
一维距离和最小原则:取中位数,7个点中位数为7;
距离和:6+4+3+0+3+8+13=37。
答案:A
第15题
题干:10个顶点无向图,4个度为3,其余度为4,求边数?
A. 36 B. 18 C. 17 D. 20
解析:握手定理:总度数=2×边数
总度数=4×3+6×4=12+24=36,边数=36/2=18。
答案:B
二、阅读程序题(共40分)
阅读程序1(二进制计数程序)
核心逻辑:统计n的二进制位数和1的个数,x初值1(位数+1),y初值1(1的个数+1)
16. 输入3,输出3 3(√)
解析:n=3(11),两轮循环,x=3,y=3,输出正确。
17. 删除第11行++x,输出两数一定相等(×)
解析:反例n=1,x=1,y=2,两数不等。
18. 第一个数一定不小于第二个数(√)
解析:x统计二进制总位数,y统计1的个数,1的个数不可能超过总位数。
19. 循环条件改为n>=0,后果?(A 死循环)
解析:n=0时,n/2仍为0,条件恒成立,无法退出循环。
20. 输入6,输出?(C 4 3)
解析:6二进制110,3位2个1,x=4,y=3。
21. 第二个数恰好为2的次数?(C 31)
解析:y=2代表二进制只有1个1,即2的幂次,范围 \(2^0\sim2^{30}\) 共31个。
阅读程序2(高精度加法)
核心逻辑:数组倒序存储数字,逐位相加进位,固定输出max_len+1位,保留前导零
22. 输入123 456,输出0579(√)
解析:无进位,最高位c[3]=0,程序完整输出0579。
23. 输入无前置零,输出一定无(×)
解析:22题反例可证,输出存在前导零。
24. 删除carry累加,结果一定更小(×)
解析:无进位输入时,结果完全不变。
25. 输入12345 678,输出?(B 013023)
解析:逐位进位计算和为13023,程序补最高位0,输出013023。
26. 进位条件改为>10,输入95 15,输出?(A 01010)
解析:各位和为10不触发进位,数组保留10,拼接输出01010。
27. n位数字和小于10^n,输出特征?(C 长度n+1,首字符0)
解析:无最高位进位,固定输出n+1位,最高位为0。
阅读程序3(质数递归搜索)
核心逻辑:DFS递归扩展质数,逐位追加0-9,大于等于n则输出
28. 输入10,输出10行(×)
解析:仅输出9个符合条件的质数,不足10行。
29. n≤5,输出一定包含5(√)
解析:5是质数,满足x≥n,必然输出。
30. 偶数末位剪枝,输出不变(√)
解析:两位及以上偶数必不是质数,剪枝无有效数据丢失。
31. 输入24,第三行输出?(B 29)
解析:DFS优先遍历子节点,先输出233、239,第三行为29。
32. 程序说法正确的是?(D)
解析:所有多位质数均由前缀质数扩展而来,删末位必为质数。
33. 输入200,输出行数?(C 14)
解析:枚举所有合法三位质数,合计14行输出。
三、完善程序题(共30分)
完善程序1:进制减半(完整原题代码+填空解析)
题目大意:给定一个 m·n 进制的数字字符串,将其转换为 n 进制数,输出最终结果。核心思路:逐位读入原进制数位,动态维护 n 进制数组,处理进位、去除前导零。
完整原题代码(含5处填空)
cpp#include <iostream>#include <string>using namespace std;const int N = 1005;int b[N];string s;int m, n;int main(){cin >> m >> n >> s;int len = 0;for (int i = 0; i < s.size(); i++){int x = s[i] - '0';// 填空1:整体进位左移,等价旧值 * mfor (int j = len; j >= 1; j--)b[j] = ____①____; b[0] = ____②____; // 填空2:最低位赋值当前数位// 处理n进制进位int carry = 0;for (int j = 0; j <= len; j++){int total = b[j] + carry;b[j] = total % n;carry = ____③____; // 填空3:计算新进位}if (carry > 0)b[++len] = carry;// 填空4:本位保留余数(真题隐含逻辑补全)b[j] = ____④____;}// 填空5:去除高位前导零while (____⑤____) len--;for (int i = len; i >= 0; i--)cout << b[i];return 0;} |
逐空答案+精准解析
34. ① D. b[j-1] * m:遍历高位区间,将原有n进制整体左移,等价数值 × m,适配原进制mn的进位规则。
35. ② B. x:所有高位完成移位后,最低位空出,存入当前读取的原进制数位x,完成 旧值×mn + x 的数值更新。
36. ③ D. b[j] / n:n进制进位规则,每一位满n进1,进位值为当前位数值整除n的商。
37. ④ B. b[j] % n:进位后本位保留余数,保证单个数位合法(0~n-1)。
38. ⑤ C. len >1 && b[len-1]==0:循环去除高位前导零,保留数值为0的特殊情况,避免输出空串。
完善程序2:平衡分割(完整原题代码+填空解析)
题目大意:给定十六进制数字字符串,将其分割为恰好 k 段,计算每段数值的平均值,求所有分割方案中,平均值极差(最大值-最小值)的最小值。
完整原题代码(含5处填空)
cpp#include <iostream>#include <string>#include <algorithm>#include <cmath>using namespace std;const double INF = 1e9;string s;int n, k;double ans = INF;// 填空1:字符转十六进制数值int get_val(char c){if (c >= '0' && c <= '9') return c - '0';else return c - 'A' + 10;}// pos:当前起始位置,cnt:已分段数// maxa:当前最大平均值,mina:当前最小平均值void dfs(int pos, int cnt, double maxa, double mina){if (cnt == k){if (pos == n)ans = min(ans, maxa - mina);return;}// 填空2:枚举当前段的结束位置for (____②____){double sum = 0;for (int i = pos; i <= r; i++){// 填空3:累加当前区间所有字符数值sum += ____③____;}// 填空4:计算当前段平均值double avg = ____④____;// 填空5:递归更新状态dfs(r + 1, cnt + 1, max(maxa, avg), min(mina, avg));}}int main(){cin >> s >> k;n = s.size();dfs(0, 0, 0, INF);printf("%.2lf\n", ans);return 0;} |
逐空答案+精准解析
39. ① A:自定义转换函数,数字字符转0-9,大写字母A-F转10-15,标准十六进制字符转换规则。
40. ② A. int r=l ; r<=n ; r++:枚举以当前pos为起点的所有合法结束位置,遍历所有可能分段区间。
41. ③ A. get_val(s[r]):遍历分段内每个字符,累加对应的十六进制数值,得到分段总和。
42. ④ B. 1.0 * sum /(r-l+1):强制浮点运算,避免整数除法截断误差,精准计算分段平均值。
43. ⑤ A:递归更新起始位置、分段数,同步更新全局最大/最小平均值,遍历所有分割方案。