2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen)

四季读书网 2 0
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen)
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第1张
一、单选题(每题2分,共30 
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第2张

第 题 如果字符变量 _1 的值是字符 ,那么 int_1 的值是?( )。

A. 1

B. -1

C. 49

D. +1 或者 -1

【答案】C

【考纲知识点】

字符的 ASCII 编码:C++ 中char类型本质是存储字符对应的 ASCII 码值,将char强转为int时,会返回该字符的 ASCII 十进制值。

  • 字符'0'的 ASCII 值为 48,因此字符'1'的 ASCII 值为48+1=49

【解析】

A:错误,'1'的 ASCII 值不是 1,1 是字符代表的数字,不是编码值。

B:错误,无逻辑依据。

C:正确,字符'1'的 ASCII 值为 49,强转int后为 49。

D:错误,ASCII 值固定,不存在正负变化。

第 题 a,b是整型变量,各自有互不相同的初始值。下列程序实现了什么效果( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第3张

A. a,b 的值从始至终都没有改变。

B. a,b 的值实现了互换。

C. a,b 的值互换了以后,又还回去了,相当于没有变化。

D. a,b 的值最后和原值不一样,没有任何意义。

【答案】B

【考纲知识点】

按位异或^运算的性质

  1. 交换律:a ^ b = b ^ a
  2. 自反性:a ^ a = 0a ^ 0 = a
  3. 结合律:(a ^ b) ^ c = a ^ (b ^ c)

【解析】

推导过程

设初始值:a = Ab = B

  1. 执行a = a ^ b→ a = A ^ Bb = B
  2. 执行b = a ^ b → b = (A ^ B) ^ B = A ^ (B ^ B) = A ^ 0 = A,此时a = A^Bb = A
  3. 执行a = a ^ b → a = (A ^ B) ^ A = B ^ (A ^ A) = B ^ 0 = B最终:a = Bb = A,完成了两个变量的无临时变量交换

A:错误,变量值发生了交换。

B:正确,代码实现了 a、b 的互换。

C:错误,最终值为交换后的值,没有还原。

D:错误,这是经典的无临时变量交换算法,有明确意义。

第 题 关于下列正确的程序段,说法正确的是( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第4张
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第5张

【答案】C

【考纲知识点】

1、两个数组的本质区别

数组
初始化方式
存储内容
数组长度
结束符
str1
双引号 "Hello"
{'H','e','l','l','o','\0'}
6 字节
'\0'(字符串结束标志)
str2
花括号 {'H','e','l','l','o'}
{'H','e','l','l','o'}
5 字节
'\0'

数组名的本质:C++ 中数组名是指向数组首元素的常量指针,str1 == str2 比较的是两个数组的首地址,而非数组内容。

两个数组是独立的内存空间,因此str1和str2的地址永远不相等,即str1 != str2恒成立。

【解析】

A 选项:错误。str1末尾有'\0',str2没有,数组内容、长度均不同,不是完全相同。

B 选项:错误。cout << str2 << endl 由于没有 '\0' 终止,会一直输出直到遇到内存中的空字符,行为未定义,不一定总是输出不同(可能巧合输出相同,但不可靠),因此B不严谨

C 选项:正确。无论从内容还是地址,两个数组都不相等,描述绝对成立。

str1 由字符串字面量 "Hello" 初始化,实际存储为 {'H','e','l','l','o','\0'},长度6。

str2 由字符列表初始化,存储为 {'H','e','l','l','o'},长度5,无结尾空字符。

因此两个数组大小不同、内容不同,它们不相等

D 选项:错误。两种赋值方式的存储内容、长度均不同,不是完全相同。

字符串自动加\0:双引号初始化自动补结束符,花括号初始化不补,输出时str2会乱码。

第 题 关于以下程序段,说法正确的是( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第6张

A. C++11 标准中,这是未定义行为,不同的环境有可能出现不同的结果

B. 22

C. 21

D. 20

【答案】B

【考纲知识点】

1. 自增运算符的本质

后置自增 x++:先返回x的当前值,再将x自增 1

前置自增 ++x:先将x自增 1,再返回x的新值

2. 求值顺序的关键说明

C++17 之前(含 C++11):+运算符的左右操作数没有规定求值顺序,属于未定义行为 (UB),编译器可以自由选择先算左操作数、先算右操作数,甚至交错执行,因此结果不固定。

部分编译器(如 GCC、MSVC 的默认实现):会采用 「从右到左」求值  的顺序,这是最常见的实现,此时会得到22的结果,这也是很多教材 / 考试中默认的计算逻辑。

【解析】

「从右到左」求值的计算过程(得到 22 的推导)

(1)初始值:x = 10

(2)先计算右操作数 ++x:

        前置自增,x先加 1 → x = 11,返回11

(3)再计算左操作数 x++:

        后置自增,返回x的当前值11,然后x加 1 → x = 12

(4)计算加法:11 + 11 = 22,最终输出22

其他求值顺序的可能结果(说明未定义行为)

「从左到右」求值(部分编译器 / 优化下的结果)

(1)初始值:x = 10

(2)先算左操作数x++:返回10,x变为11

(3)再算右操作数++x:x变为12,返回12

(4)加法:10 + 12 = 22(巧合结果相同)

注:部分编译器会得到21,是因为求值顺序的交错优化,属于未定义行为的正常表现。

A 选项:从 C++ 标准的严谨角度,该表达式在 C++11 中是未定义行为,这是标准层面的正确结论。尽管 C++ 标准中此类表达式属于未定义行为,但在大多数常见编译器(如 GCC、MSVC 未开启严格警告时)实际运行结果为 22。

B 选项:在绝大多数编译器的默认实现(从右到左求值)下,输出结果为22,是考试 / 编程实践中最常见的结果,因此很多题目会将 B 作为正确答案。

C/D 选项:仅在特定编译器 / 优化下可能出现,不是主流结果。

第 题 位二进制下,十进制数-15 的补码是( )。

A. 11110000

B. 10001111

C. 10010000

D. 11110001

【答案】D

【考纲知识点】

补码的计算规则(8 位带符号整数)

1、正数:原码 = 反码 = 补码,符号位为 0

2、负数:补码 = 原码除符号位取反 + 1

步骤:

(1)求 15 的 8 位原码:00001111

(2)求 - 15 的原码:符号位变 1 → 10001111

(3)求反码:除符号位取反 → 11110000

(4)补码:反码 + 1 → 11110001

【解析】

A:11110000是 - 15 的反码,不是补码,错误。

B:10001111是 - 15 的原码,错误。

C:10010000无对应关系,错误。

D:11110001是 - 15 的补码,正确。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第7张

A. 63

B. 65

C. 67

D. 69

【答案】B

【考纲知识点】

r 进制转十进制的按权展开法

  • 公式:对于 r 进制数 dₙdₙ₋₁...d₁d₀,十进制值 = dₙ×rⁿ + dₙ₋₁×rⁿ⁻¹ + ... + d₁×r¹ + d₀×r⁰

【解析】

计算过程

三进制数2102,从右到左权值为3⁰, 3¹, 3², 3³

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第8张

第 题 二进制数 10110101 是某数的 位补码,该数的十进制是( )。

A. -73

B. -75

C. -77

D. 75

【答案】B

【考纲知识点】

补码转十进制(8 位带符号整数)

  • (1)补码最高位为符号位:0表示正数,1表示负数
  • (2)正数:补码直接转十进制
  • (3)负数:补码 → 原码(补码除符号位取反 + 1) → 十进制

【解析】

计算过程

补码10110101,符号位为1,是负数:

  1. 除符号位取反:11001010
  2. 加 1 得到原码:11001011
  3. 原码转十进制:符号位1表示负,数值部分1001011
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第9张

因此该数为-75

补码计算:负数补码 = 反码 + 1,补码转负数 = 取反 + 1 加负号

【总结】

负数补码 → 原码的两种方法(8 位)

已知:补码 = 10110101(对应 -75)

方法①:补码 减 1 → 再按位取反(符号位不变)

  1. (1)补码:1011 0101
  2. (2)减 1:1011 0100
  3. (3)符号位不动,其余取反:1100 1011 → 原码

方法②:补码 除符号位取反 → 再 +1

  1. (1)补码:1011 0101
  2. (2)符号位不动,其余取反:1100 1010
  3. (3)加 1:1100 1011 → 原码

第 题 已知 unsigned char c = 0x0F; (十六进制 0F 二进制 00001111 ),执行 c = c << 3; 后, 的十进制值是:( )。

A. 64

B. 72

C. 80

D. 120

【答案】D

【考纲知识点】

左移运算符 <<

  • (1)无符号数左移 n 位,等价于乘以 2ⁿ,高位溢出丢弃,低位补 0。
  • (2)unsigned char是 8 位无符号整数,范围 0~255。

【解析】

计算过程

  1. 初始值:0x0F = 二进制 0000 1111 = 十进制 15
  2. 左移 3 位:0000 1111 << 3 = 0111 1000
  3. 二进制 01111000 转十进制:64+8+4+2+0=120
  4. 左移运算:无符号数左移 n 位 = 乘2ⁿ,高位丢弃,低位补 0

第 题 补码的情况下,关于按位取反运算,用笔计算的情况下,以下说法错误的是:( )

A. ~5 的结果是 -6( int 类型,32 位)

B. ~0 的结果是 0( int 类型,32 位)

C. ~(-3) 的结果是 2( int 类型,32 位)

D. ~8 的结果是 -9( int 类型,32 位)

【答案】B

【考纲知识点】

按位取反 ~ 运算规律:对于任意整数 x,有公式:~x = -x - 1(32 位补码系统中恒成立)

  • 原理:补码按位取反后,等于原数的相反数减 1。

【解析】

A 选项:~5 = -5 -1 = -6 ✅ 正确

B 选项:~0 = -0 -1 = -1,不是 0 ❌ 错误

C 选项:~(-3) = -(-3) -1 = 3 -1 = 2 ✅ 正确

D 选项:~8 = -8 -1 = -9 ✅ 正确

按位取反公式:~x = -x - 1,直接秒算结果

第 10 题 执行以下 C++ 代码后, sub 的值是( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第10张

A. 20

B. 02

C. 2026

D. 026

【答案】A

【考纲知识点】

string::substr(pos, len) 函数:

pos:从 0 开始计数的起始下标

len:截取的字符长度

功能:从字符串的 pos 位置开始,截取 len 个字符。

【解析】

字符串下标拆解

str = "GESP2026",下标从 0 开始:

下标
0
1
2
3
4
5
6
7
字符
G
E
S
P
2
0
2
6

substr(4, 2):从下标 4 开始,截取 2 个字符 → 字符2(下标 4)、0(下标 5)

最终 sub = "20"

substr 函数:下标从 0 开始,第一个参数是起始位置,第二个是截取长度

第 11 题 执行以下代码后,输出结果是:( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第11张

A. 4

B. 6

C. 24

D. 30

【答案】B

【考纲知识点】

sizeof运算符计算数组长度

sizeof(arr):返回整个数组占用的总字节数

sizeof(arr[0]):返回数组单个元素占用的字节数

数组长度 = 总字节数 ÷ 单个元素字节数

【解析】

计算过程

数组arr有 6 个int元素,int占 4 字节

sizeof(arr) = 6 × 4 = 24

sizeof(arr[0]) = 4

count = 24 / 4 = 6

数组长度计算sizeof(数组) / sizeof(数组[0]) 是通用公式,适用于所有基础类型数组

第 12 题 执行以下代码后,输出结果是:( )。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第12张

A. 4

B. 5

C. 6

D. 10

【答案】B

【考纲知识点】

sizeof与strlen的区别

sizeof(s):返回数组s的总字节数(数组定义长度为 10,因此总字节数为 10)

sizeof(s[0]):单个char占 1 字节,因此a = 10 / 1 = 10

strlen(s):返回字符串的有效长度(不含末尾'\0'),"abcde"长度为 5,因此b = 5

【解析】a - b = 10 - 5 = 5

sizeof vs strlensizeof算数组总长度,strlen算字符串有效长度(不含'\0'

第 13 题 以下问题中,最不适合用枚举法解决的是:( )

A. 找出 1~100 之间所有能被 整除的数

B. 找出 100~200 之间的所有质数

C. 计算 1+2+3+…+1000 的和

D. 找出三位数中个位、十位、百位数字之和等于 10 的数

【答案】C

【考纲知识点】

枚举法:逐一遍历所有可能的情况,判断是否满足条件,适合数据范围小、遍历成本低的问题

不适合枚举的场景:有明确数学公式、可直接计算的问题(枚举会做无用功,效率极低)

【解析】

A 选项:1~100 范围小,可枚举遍历,适合枚举

B 选项:100~200 范围小,可枚举判断质数,适合枚举

C 选项:有明确的求和公式 S = n(n+1)/2,直接计算即可,完全不需要枚举,最不适合用枚举法

D 选项:三位数共 900 个,范围小,可枚举遍历,适合枚举

枚举法适用场景:范围小、无公式、需逐一判断的问题;有公式的问题优先用公式,不枚举

第 14 题 用枚举法解决 鸡兔同笼问题:头共 35 个,脚共 94 只,求鸡和兔的数量,以下枚举逻辑最合理的是:()

A. 枚举鸡的数量 0~35),兔的数量 y=35-x ,判断 2*x + 4*y == 94

B. 枚举兔的数量 0~94),鸡的数量 x=35-y ,判断 2*x + 4*y == 94

C. 枚举所有整数 0-100)和 0-100),判断 x+y==35 && 2*x+4*y==94

D. 枚举脚的总数 sum 0~94),判断 sum == 94

【答案】A

【考纲知识点】

枚举法的核心是减少无效遍历、缩小枚举范围,利用已知条件减少枚举次数,提升效率。

鸡兔同笼的核心约束:

(1)总头数 = 鸡数 + 兔数 = 35 → 兔数 = 35 - 鸡数,无需同时枚举两个变量

(2)鸡有 2 只脚,兔有 4 只脚 → 总脚数 = 2× 鸡数 + 4× 兔数

【解析】

A 选项:✅ 最合理。

仅枚举鸡的数量 x(范围 0~35,仅 36 次遍历),兔数由总头数直接算出,无冗余计算,效率最高,逻辑最严谨。

B 选项:❌ 不合理。

枚举兔的数量 y 的范围错误(兔数最多 35 只,而非 0~94),范围过大,存在无效遍历。

C 选项:❌ 不合理。

双重枚举 x 和 y,遍历次数达 101×101=10201 次,存在大量无效计算,完全浪费,不是最优逻辑。

D 选项:❌ 完全错误。

仅枚举脚的总数,无法区分鸡和兔的数量,无法解决问题。

第 15 题 模拟 字符串加密:规则为 每个字符 ASCII 码 + 3,若超过 (122) 则从 重新开始,以下代码中正确的条件判断是:( )

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第13张

A. if (str[i]> 122) str[i] = str[i] + 3 - 26;

B. if (str[i] > 122) str[i] = str[i] - 26;

C. if (str[i] + 3 > 122) str[i] = str[i] - 23;

D. if (str[i] + 3 > 'z') str[i] = 'a' + (str[i] + 3 - 'z') - 1;

【答案】D

【考纲知识点】

字符加密的循环逻辑:

1、小写字母a的 ASCII 码为 97,z为 122,共 26 个字母。

2、加密规则:字符 + 3,若超过z(122),则绕回a重新开始,等价于:

若原字符+3 > 122,则新字符 = a + (原字符+3 - z - 1)(或等价的原字符+3-26)

【解析】

A 选项:❌ 错误。

判断条件错误:判断的是原字符+3>122,而非原字符>122,逻辑完全错误。

B 选项:❌ 错误。

判断条件错误(同 A),且赋值逻辑错误,无法正确绕回。

C 选项:❌ 错误。

str[i] -23 等价于 str[i]+3-26,赋值逻辑正确,但判断条件str[i]+3>122的写法不直观,且与 D 选项的可读性、严谨性相比,不是最优。

D 选项:✅ 正确。

1、判断条件if (str[i] + 3 > 'z'):用字符常量'z'替代 122,可读性强,逻辑严谨。

2、赋值逻辑'a' + (str[i] + 3 - 'z') - 1:

(1)计算原字符+3超过z的偏移量,绕回a,完全符合规则。

(2)例如:y(121)+3=124>122 → 'a' + (124-122)-1 = 97 +2-1=98 → b,正确。

(3)z(122)+3=125>122 → 'a' + (125-122)-1=97+3-1=99 → c,正确。字符加密循环:判断原字符+3 > 'z',绕回a的公式:'a' + (原字符+3 - 'z') - 1

二、判断题(每题2分,共20
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第14张

第 题 定义 int arr[5] = {1,2,3}; ,则 arr[3] 的值为 0, arr[5] 是合法下标。

【答案】×

【考纲知识点】数组的定义与下标访问

【解析】

1、不完全初始化:当数组初始化元素个数少于定义长度时,剩余元素自动初始化为 0。

arr[5] 包含 5 个元素:{1, 2, 3, 0, 0},所以 arr[3] = 0 ✅。

2、下标范围:数组下标从 0 开始,长度为 n 的数组,合法下标范围是 0 到 n-1。

本题数组长度为 5,合法下标为 0~4,arr[5] 越界 ❌。

第 题 定义 double arr[10]; ,未手动初始化时,数组中所有元素的默认值为 0.0

【答案】×

【考纲知识点】局部数组 vs 全局 / 静态数组

【解析】

  • 局部数组
    (函数内定义):未初始化时,内容是随机的垃圾值,不是 0。
  • 全局数组
     或 静态数组static 修饰):未初始化时,自动初始化为 0。

题目未说明作用域,默认按局部数组处理,因此默认值不是 0.0。

第 题 定义 int arr[] = {1,2,3}; ,则 sizeof(arr) 的结果为 12( int 占 字节)。

【答案】√

【考纲知识点】sizeof 计算数组大小

【解析】

arr[] = {1,2,3} 表示长度为 3 的数组。

sizeof(arr) = 元素个数 × 单个元素大小 = 3 × 4 = 12 字节。

第 题 下面的流程图是用来求 1+2+3+…+10 的和。

请判断:这个流程图的逻辑正确还是错误?

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第15张

【答案】√

【考纲知识点】循环结构逻辑(for/while 等价)

【解析】

流程图逻辑:

  1. 开始 sum=0, i=1
  2. 判断 i <= 10
    • 是:执行 sum = sum + i → i = i + 1 → 回到判断。
    • 否:输出 sum。

第 题 下面流程图的功能是计算 对 取余数,输出结果为 1

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第16张

【答案】√

【考纲知识点】流程图的执行流程(辗转相减逻辑)

【解析】

流程图逻辑:

  1. 初始化 a=5, b=2
  2. 判断 a >= b
    • 是:a = a - b (5-2=3) → 回到判断。
    • 否:输出 a。

执行过程

  • 初始 a=5, b=2
  • 5 >= 2 → a=3
  • 3 >= 2 → a=1
  • 1 < 2 → 输出 1
  • 结果为 1,与 5%2=1 一致。

第 题 已知大写字符 ASCII编码的十六进制表示为 0x41 ,计算字符 ASCII编码的八进制表示为 155(八进制)。

【答案】√

【考纲知识点】进制转换与字符编码

【解析】八进制 155 转十进制:

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第17张

十进制 109 对应的 ASCII 字符就是 'm'

第 题 在 C++ 位运算中,各种不同的运算符有优先级的区分,使用括号能够解决优先级的问题。

【答案】√

【考纲知识点】运算符优先级与结合性

【解析】

括号 () 的优先级最高,使用括号可以强制改变运算顺序,消除优先级歧义。

例如:a + b * c 默认先乘后加,(a + b) * c 先加后乘。

第 题 由于在 0~255 范围内, char 类型和 int 类型可以互换,因此在这里 和 相等。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第18张

【答案】×

【考纲知识点】类型本质与隐式转换

【解析】

char x='1':存储的是字符 '1' 的 ASCII 码值,即 49

int y=1:存储的是整数 1

虽然 char 在 0~255 范围内可以与 int 互换存储,但值并不相等(49 ≠ 1)。

第 题 C++语言中,表达式 ((0xf0 + 0x15) == 255) 的值为 true 

【答案】×

【考纲知识点】十六进制加法与进制转换

【解析】

1、十六进制转十进制:

0xf0 = 15×16 + 0 = 240

0x15 = 1×16 + 5 = 21

2、相加:240 + 21 = 261。

3、比较:261 ≠ 255。

第 10 题 如果 为 int 类型的变量,且 的二进制最低位为 ,则表达式 ((a & 3 & 1) == 0) 的值为true 

【答案】√

【考纲知识点】位运算(按位与 &

【解析】

1、最低位为 0 → 表示 a 是偶数。

2、a & 1:用于判断最低位。结果为 0 说明最低位是 0。

3、运算优先级:& 优先级高于 ==,但结合性为从左到右。

(1)a & 3 & 1 = (a & 3) & 1。

(2)因为 a 最低位为 0,所以 a & 1 结果必为 0,整个表达式值为 true。

三、编程题(每题 25 分,共 50 分)

3.1 编程题 1

试题名称:二进制回文串

时间限制1.0 s

内存限制512.0 MB

3.1.1题目描述

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第19张

【考纲知识点】

1、进制转换:将十进制数转换为二进制字符串

2、回文数判断:验证字符串正序与逆序是否完全一致

3、枚举法:遍历指定范围,筛选符合条件的数

【解题思路】

采用暴力枚举法最直观且符合数据范围要求(n≤105,最大循环 10 万次,效率完全足够)。

算法步骤:

1、输入数据:读取正整数 n

2、初始化计数器:count = 0

3、遍历区间:从 1 到 n 逐个检查

4、二进制转换:将每个数转为不含前导零的二进制字符串

5、回文判断:比较字符串与反转后的字符串是否相等

6、统计结果:符合条件的数计数器加 1

7、输出结果:打印最终计数器值

【参考程序1】(用字符串存二进制)

#include<iostream>#include<string>#include<algorithm>using namespace std;// 十进制转二进制字符串string toBinary(int n){    if (n == 0return "0";    string res;    while (n > 0) {        res += (n % 2) ? '1' : '0';        n /= 2;    }    reverse(res.begin(), res.end());    return res;}// 判断回文boolisPalindrome(const string& s){    int l = 0, r = s.size() - 1;    while (l < r) {        if (s[l] != s[r]) return false;        l++; r--;    }    return true;}intmain(){    int n;    cin >> n;    int cnt = 0;    for (int i = 1; i <= n; ++i) {        string bin = toBinary(i);        if (isPalindrome(bin)) {            cnt++;        }    }    cout << cnt << endl;    return 0;}
【备注】:reverse(res.begin(), res.end()); 的作用
把一个字符串 从头到尾 反转过来。

因为算二进制的时候,算出来是反的

比如数字 5 → 二进制应该是 101

但我们用 %2/2 算出来的顺序是:先得到最低位 1 → 然后 0 → 然后最高位 1所以算出来是 101 倒着存的 → "101"

刚好这题是回文,所以结果一样,但原理必须懂

二进制转换的反转:必须保留(因为%2//2法生成的是逆序,不反转就不是正确的二进制。得到的是逆序二进制,回文判断会出错

比如数字 6(二进制110):

计算:6%2=0 → res="0",6/2=3

3%2=1 → res="01",3/2=1

1%2=1 → res="011"

此时 res 是 "011",是反的,正常二进制是110,所以必须反转成"110"

【参考程序2】(用数组存二进制)

#include<iostream>using namespace std;intmain(){    int n, a[50] = {0}, ans = 0;    cin >> n;    for (int i = 1; i <= n; i++) {        int t = i;        int pos = 0;        // 1. 转二进制,低位存在前        while (t) {            a[pos++] = t % 2;            t /= 2;        }        // 2. 判断回文 (核心逻辑未变)        bool is_pal = true;        // 只需循环一半长度,减少比较次数        for (int j = 0; j < pos / 2; j++) {             if (a[j] != a[pos - 1 - j]) {                is_pal = false;                break// 只要有一个不等,直接退出            }        }        if (is_pal) ans++;    }    cout << ans << endl;    return 0;}

1. 二进制转换(存的是逆序,但刚好能用)

原理:比如 t = 6 (110)

第一次循环:6%2=0 → a[0] = 0 (对应二进制最低位)

第二次循环:3%2=1 → a[1] = 1

第三次循环:1%2=1 → a[2] = 1 (对应二进制最高位)

结果:数组里存的是 a = [0, 1, 1]。

注意:这和正常二进制 110 是逆序的。

这里转二进制不用反转。

3.2 编程题 2

试题名称:凯撒密码

时间限制1.0 s

内存限制512.0 MB

3.2.1 题目描述

凯撒密码是一种替换加密技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是 3的时候,所有的字母A 将被替换成D , B被替换成E ,C 被替换成 F,以此类推,W被替换成Z ,X 被替换成 A, Y被替换成B , Z被替换成 C。这个加密方法是以罗马共和时期凯撒的名字命名的,据称当年凯撒曾用此方法与其将军们进行联系。

但是和所有的利用字母表进行替换的加密技术一样,凯撒密码非常容易被破解,而且在实际应用中也无法保证通信安全。

现在给你一个已破解的凯撒密码明文与密文,与一个有相同偏移量的未破解凯撒密码密文,请你帮忙破解它。

3.2.2 输入格式

输入共三行:

第一行包含一个字符串,表示已破解的凯撒密码明文;

第二行包含一个字符串,表示已破解的凯撒密码密文;

第三行包含一个字符串,表示待破解的凯撒密码密文。

3.2.3 输出格式

输出一行,包含一个字符串,表示待破解的凯撒密码对应的明文。

2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第20张

【考纲知识点】

1、ASCII 码运算:利用字符的 ASCII 码数值差计算偏移量。

(1)大写字母 A-Z 的 ASCII 码范围是 65-90。

(2)偏移量 key = 密文字符 - 明文字符(取模处理循环)。

2、模运算(%):处理字母表的循环特性(如 W 偏移 3 变 Z,X 偏移 3 变 A)。

公式:(c - 'A' + 26) % 26 确保结果在 0-25 之间,避免负数。

3、字符映射:根据偏移量,对目标密文逐字符进行逆向偏移。

【解题思路】

1、计算偏移量 key:

(1)输入已知的明文 s1 和密文 s2。

(2)取第一个字符(或任意对应位置字符)计算:key = (s2[0] - s1[0] + 26) % 26。

(3)原理:偏移量是固定的,key = 密文 - 明文。

2、破解目标密文:

(1)输入待破解的密文 s3。

(2)遍历 s3 的每个字符 c:

(3)计算公式:明文 = (c - 'A' - key + 26) % 26 + 'A'。

(4)加 26 再取模是为了防止负数(例如 c='A',key=3,0-3=-3,加 26 得 23,模 26 仍为 23,对应 X)。

3、输出结果:拼接所有解密后的字符并输出。

【参考程序】

#include<iostream>#include<string>using namespace std;intmain(){    string plain, cipher, target;    // 1. 读取输入    cin >> plain >> cipher >> target;    // 2. 计算偏移量 key (D'-'A' = 3)    int key = (cipher[0] - plain[0] + 26) % 26;    // 3. 逐字符解密并输出    for (char c : target) {        // 核心公式:(当前字符 - 基准 - 偏移 + 26) % 26 + 基准        int decrypted = (c - 'A' - key + 26) % 26 + 'A';        cout << (char)decrypted;    }    cout << endl;    return 0;}

易错点避坑

1、负数处理:必须在计算时加 26 再取模,否则会出现负数导致错误(如 'A' - 1 会变成乱码)。

2、大小写混淆:题目保证全大写,无需处理小写。

3、偏移方向:题目要求逆向解密,必须用 (c - key),而不是 (c + key)。

【加入我们,让孩子在信息学赛道上跑得更快、更稳!欢迎关注留言!】
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第21张
2026 年 3 月 GESP C++ 三级真题解析(负数补码转原码2种方法、按位取反规律、sizeof vs strlen) 第22张

抱歉,评论功能暂时关闭!