阅读程序 · 答案 BA · 考点:字符数组与字符串处理、循环结构、字符串(string)
← 整套速查表 CSP-J 入门级 全部真题二、阅读程序(程序输入不超过数组或字符串定义的范围;判断题正确填 √,错误填 ×;除特殊说明外,判断题 $1.5$ 分,选择题 $3$ 分,共计 $40$分)
1.
#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;
} 1. 输入的字符串只能由小写字母或大写字母组成。() 2. 若将第 $8$ 行的 i = 1 改为 i = 0,程序运行时会发生错误。() 3. 若将第 $8$ 行的 i <= n 改为 i * i <= n,程序运行结果不会改变。() 4. 若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。()
5. 若输入的字符串长度为 $18$,那么输入的字符串跟输出的字符串相比,至多有()个字符不同。
6. 若输入的字符串长度为(),那么输入的字符串跟输出的字符串相比,至多有 $36$ 个字符不同。
这题考的是‘因数遍历’与‘数组下标偏移’的结合。拿到程序先别急着看条件,先想:循环 i 从 1 到 n,里面用的是 st[i-1],说明 i 代表的是‘第几个字符’,而判断 n%i==0 是在找 n 的因数。核心思路就是:找出 n 的所有因数,把对应位置的小写字母转大写,大写字母和符号不动。
最容易踩的坑有两个:一是把 n%i==0 理解反了,当成 i 是 n 的倍数,其实这是找因数;二是数组下标从 0 开始,但循环 i 从 1 开始,所以访问的是 st[i-1],改错时千万别写成 st[i] 否则越界。判断题里,第 3 问很多人以为改 i*i<=n 只是范围变小,其实漏掉大因数会导致结果完全不一样,必须记住因数成对出现,只遍历到 sqrt(n) 得配对处理,这里没配对所以必错。选择题第 5 问要数 18 的因数个数,别漏了 1 和 18 自己,一共 6 个,对应最多 6 个字符不同。
这题是典型的‘阅读程序 + 逻辑推理’题,核心考查三个点: 1. 循环结构与数组下标偏移:循环变量 i 从 1 到 n,但数组是 st[i-1],i 代表‘第几个字符’,下标是 i-1。 2. 因数遍历逻辑:条件 n%i==0 是在找 n 的因数,而不是倍数。 3. 字符转换条件:只有小写字母(c >= 'a')才会被转大写,其他字符(包括大写字母、数字、符号)完全不受影响。
命题人喜欢在这里埋两个雷:
拿到这种题,别急着看选项,先自己走一遍程序逻辑: 1. 输入字符串 st,长度 n = strlen(st)。 2. 循环 i 从 1 到 n,每次检查 n%i==0。 3. 如果成立,取出字符 c = st[i-1]。 4. 如果 c >= 'a',就把 c 转大写:st[i-1] = c - 'a' + 'A'。 5. 最后输出 st。
本质就是:对字符串中所有‘位置索引是 n 的因数’的字符,如果是小写就转大写。
分析:scanf("%s", st) 会读取任意非空字符串,直到遇到空白字符(空格、换行等)。题目里没有限制输入内容,所以输入可以是数字、符号、中文等。程序里只判断 c >= 'a',意思是只有小写字母会被转换,但其他字符(比如 '1'、'@')既不会被转大写,也不会报错。
结论:输入可以是任何字符,所以这题选 B(错误)。