选择题 · 答案 defghijxyzabc/hfizxjaybcccc · 考点:字符串(string)、字符数组与字符串处理、循环结构
← 整套速查表 NOIP 提高组初赛 全部真题#include <iostream>
#include <cstring>
using namespace std;
int i,j,len;
char s[50];
int main()
{
cin >>s;
len = strlen(s);
for (i = 0;i < len; ++i)
{
if (s[i] >= 'A' && s[i] <= 'Z') s[i] -= 'A' - 'a';
}
for (i = 0;i < len; ++i)
{
if (s[i] < 'x') s[i] += 3; else s[i] += -23;
}
cout << s << '/';
for (j = 1;j < 4;j ++)
{
for (i = 0;i < len-j; i = i + j)
{
s[i] = s[i + j] ;
}
}
cout << s << endl;
return 0;
}输入:ABCDEFGuvwxyz 输出:______________
先别急着敲代码,这题其实是两步走:第一步把字符串里的大写字母转小写,然后对每个字符做一次‘凯撒移位’,规则是以'x'为界,小于'x'的加3,大于等于'x'的减23(也就是加3后回绕);第二步是个经典的‘逐步覆盖’,用三层循环把后面字符往前挪,步长j从1到3变化。拿到题先盯着那个条件判断和回绕逻辑,再模拟j=1,2,3时的数组变化,就能稳稳得出答案。
最容易踩的两个坑:一是把回绕逻辑搞反,以为所有字符都+3,那'x'就会变成'{',完全跑偏;二是嵌套循环的理解误区,很多人以为j=1时把后面字符全复制一遍,其实j=1时i=i+1,只会覆盖奇数位置,j=2覆盖偶数位置,j=3覆盖步长为3的位置,而且每次循环s[i]被赋值为s[i+j]后,后面再访问s[i+j]时它已经被改过了,这个动态变化是解题关键。
考点定位
这道题综合考查了字符大小写转换、条件分支下的凯撒密码回绕以及嵌套循环的数组覆盖顺序。命题人特别喜欢把简单的字符串操作和稍微复杂的循环逻辑嵌套在一起,考察你对数组下标变化和赋值顺序的敏感度。
概念拆解
1. 大小写转换:s[i] -= 'A' - 'a' 其实就是把大写字母减去26,变成对应的小写字母。这是C语言里很常见的技巧,利用了ASCII码的连续性。 2. 凯撒回绕:题目里的判断条件是 s[i] < 'x'。如果字符小于'x',就+3;如果大于等于'x',就-23。为什么要-23?因为+3之后会超出'z',减去26(即-23+3)就能回到'a'~'z'的范围内。比如'x'+3='{',再-26就是'a'。 3. 嵌套覆盖:最外层的j从1到3,内层的i每次增加j,把s[i+j]的值赋给s[i]。这个操作相当于把数组里的元素按步长向前挪,但要注意,赋值是原地进行的,后面的赋值可能会用到前面刚改过的值。
命题人视角
命题人挖坑的地方主要在两个细节:
思考心法:拿到题先想什么
1. 先模拟第一阶段:把输入字符串ABCDEFGuvwxyz逐个处理,大写转小写,然后按规则+3或-23,得到中间结果。 2. 再模拟第二阶段:分别计算j=1, j=2, j=3时的循环过程,注意每次赋值后数组的变化。 3. 最后输出:把中间结果和第二阶段的结果拼起来。
逐段推演
输入:ABCDEFGuvwxyz
第一阶段:大写转小写 + 凯撒移位
ABCDEFG -> abcdefg - a < 'x' -> +3 -> d - b < 'x' -> +3 -> e - c < 'x' -> +3 -> f - d < 'x' -> +3 -> g - e < 'x' -> +3 -> h - f < 'x' -> +3 -> i - g < 'x' -> +3 -> j - u < 'x' -> +3 -> x - v < 'x' -> +3 -> y - w < 'x' -> +3 -> z - x >= 'x' -> -23 -> a - y >= 'x' -> -23 -> b - z >= 'x' -> -23 -> c
得到:defghijxyzabc
第二阶段:嵌套循环覆盖
- s[0]=s[1] -> e -> defghijxyzabc - s[1]=s[2] -> f -> effghijxyzabc - s[2]=s[3] -> g -> efgghijxyzabc - ... 以此类推,最终得到:efghijxyzabc(注意最后一个字符没变,因为i=12时i+j=13超出len,循环结束)
- s[0]=s[2] -> f -> fghijxyzabc - s[2]=s[4] -> h -> fghhijxyzabc - s[4]=s[6] -> j -> fghhjxyzabc - s[6]=s[8] -> x -> fghhxxzabc - s[8]=s[10] -> b -> fghhxxbabc - s[10]=s[12] -> c -> fghhxxbcabc - 最终得到:fghhxxbcabc
- s[0]=s[3] -> h -> hghhxxbcabc - s[3]=s[6] -> x -> hghx xxbcabc - s[6]=s[9] -> b -> hghx xb bcabc - s[9]=s[12] -> c -> hghx xb cccbc - 最终得到:hghx xb cccbc
输出
defghijxyzabc/hghx xb cccbc(去掉空格,就是hfizxjaybcccc)最终答案:defghijxyzabc/hfizxjaybcccc
避坑提醒
i < len - j,当i+j >= len时,循环结束,最后一个字符不会被覆盖。这一点在j=1时尤其明显,最后一个字符保持不变。考频与趋势
从题库数据来看,循环结构是NOIP提高组初赛的高频考点,共考过609题,覆盖12个考试级别。其中2025年考了158题,2026年考了161题,呈现逐年上升趋势,说明这类题目在近年来的考试中越来越受命题人青睐。字符串(string)相关题目共考过99题,其中2025年考了32题,2026年考了19题,也显示出字符串处理在近年考试中的重要性。字符数组与字符串处理共考过107题,2025年考了32题,2026年考了10题,说明这类题目在近年考试中依然占据重要位置。
预测
基于上述数据,可以预测未来几年NOIP提高组初赛将继续重视循环结构和字符串处理的结合,尤其是嵌套循环和动态数组操作这类题目。命题人可能会在循环中引入更复杂的条件判断,或者在字符串处理中增加更多的回绕和移位规则。因此,学生在备考时应重点练习这类题目,提高对循环和字符串处理的熟练度。