CSP-J 入门级 · CSP 2026 入门级第一轮 第 17 题

阅读程序 · 答案 ABC · 考点:字符数组与字符串处理、高精度计算、循环结构

← 整套速查表 CSP-J 入门级 全部真题

题目

【阅读程序2】

本题输入的两个数均为非负整数,位数不超过 100000,可能包含前导零。

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
int a[100007], b[100007], c[100007], carry[100007];
string input_str;
int a_len, b_len;
int main() {
    cin >> input_str;
    a_len = input_str.size();
    for (int i = 0; i < a_len; i++) {
        a[i] = input_str[a_len - i - 1] - '0';
    }
    cin >> input_str;
    b_len = input_str.size();
    for (int i = 0; i < b_len; i++) {
        b[i] = input_str[b_len - i - 1] - '0';
    }
    carry[0] = 0;
    for (int i = 0; i < max(a_len, b_len) + 1; i++) {
        c[i] = a[i] + b[i] + carry[i];
        if (c[i] >= 10) {
            carry[i + 1] = 1;
            c[i] -= 10;
        } else {
            carry[i + 1] = 0;
        }
    }
    for (int i = max(a_len, b_len); i >= 0; i--) {
        cout << c[i];
    }
    cout << endl;
    return 0;
}
答案:ABC

考点

字符数组与字符串处理 讲解 →字符数组与字符串处理 真题汇总 →高精度计算 讲解 →高精度计算 真题汇总 →循环结构

解题思维

这是"高精度加法"的手写实现:把两个数逆序存进数组(下标 0 是个位),从低位往高位逐位相加并进位。最要紧的一点是输出循环从 max(a_len, b_len) 开始,固定比最长加数多输出一位(这一位就是最高位进位,没进位时输出 0)。

常见错误

没注意到输出长度恒为 max_len+1(第 23、27 题全靠这一点);把第 26 题的条件改成 > 10 后仍按"逢十进一"的心算习惯处理,得到 110 而不是 01010。

详细解析(节选)

程序分析

cin >> input_str;  a_len = input_str.size();
for (int i = 0; i < a_len; i++)  a[i] = input_str[a_len - i - 1] - '0';   // 逆序:a[0] 是个位
// b[] 同样处理
carry[0] = 0;
for (int i = 0; i < max(a_len, b_len) + 1; i++) {
    c[i] = a[i] + b[i] + carry[i];      // 第 21 行
    if (c[i] >= 10) { carry[i + 1] = 1; c[i] -= 10; }   // 第 22 行
    else            { carry[i + 1] = 0; }
}
for (int i = max(a_len, b_len); i >= 0; i--)  cout << c[i];   // 第 29 行

三个必须抓住的设计点:

1. 逆序存储:a[0]、b[0] 是低位,数组下标 i 对应权值 10^i。a[]、b[] 是全局数组,未赋值位置自动为 0,所以短的那个数高位自动补 0,不需要额外处理。 2. 循环上界是 max_len + 1:多算的那一位承载"最高位的进位"。 3. 输出从 c[max_len] 到 c[0],共 max_len + 1 位:因此结果长度固定,和是否发生最高位进位无关——这解释了为什么 123 + 456 会输出 0579(多了一个前导 0)。

第 22 题(判断)

123 + 456 = 579,max_len = 3,输出 c[3] c[2] c[1] c[0] = 0, 5, 7, 9 → 字符串 0579。 答案:A(正确) ✓

第 23 题(判断)

由设计点 3,输出长度恒为 max_len + 1。只要最高位没有产生进位,c[max_len] = 0,输出必然带前导零——即使两个加数都不含前导零(如 123 + 456)。所以说法错误。 答案:B(错误) ✓

第 24 题(判断)

把第 21 行改成 c[i] = a[i] + b[i]; 后不再处理进位,每一位独立相加,可能出现 ≥ 10 的"位",输出不再是合法数字串,其大小关系也不再有保证。 反例:输入 95 15。原程序输出 110(真正的和);改后输出 01010,作为数字是 1010 > 110,比原来大,"一定比原来的结果小"错误。 答案:B(错误) ✓

第 25 题(单选)

12345 + 678 = 13023,max_len = 5,输出 6 位:c[5]=0,c[4]=1,c[3]=3,c[2]=0,c[1]=2,c[0]=3 → 013023。 答案:B(013023) ✓ (A 012923、C 13023、D 130230 分别错在中间位算错、少一位、错位。)

第 26 题(单选)

把 if (c[i] >= 10) 改成 if (c[i] > 10):只有严格大于 10 才进位,等于 10 时不处理。 输入 95 15,max_len = 2:

ia[i]+b[i]+carry[i]是否 > 10carry[i+1]c[i]
05+5+0 = 10否010
19+1+0 = 10否010
20+0+0 = 0否00

输出 c[2] c[1] c[0] = 0 10 10 → 字符串 01010。 答案:A(01010) ✓

第 27 题(单选)

设两个数都是 n 位且和 < 10ⁿ,则 max_len = n、且最高位无进位(c[n] = 0)。输出循环从 i = n 到 0,共 n + 1 个字符,第一个字符恒为 '0'。 答案:C ✓ (A 与事实相反;B 长度不是 n 而是 n+1;D 最多 n+1 位,不可能到 n+2。)

本题小结

小题结论答案
22123+456 → 0579√
23输出可能含前导零×
24不进位后结果不一定更小(95+15)×
2512345+678 → 013023B
26>10 时 95+15 → 01010A
27长度恒为 n+1,首位 '0'C

套路提示:高精度加法的固定结构是"逆序存储 → 逐位相加 + 进位数组 → 反向输出"。读题时第一眼先确认输出起点和终点(本题是 max_len 到 0),很多判断题的答案就藏在这两个边界里。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断