欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总帖:GESP认证C++编程真题解析 | 汇总
单选题
第1题
8位二进制原码能表示的最小整数是:( )
A.-127
B.-128
C.-255
D.-256
【答案】:A
【解析】
注意此题问的是原码,原码第1位是符号位,后面7位是数据位。题目问能表示的最小的数,那就是最小的负数,所以符号位是1,剩下7位数据位最多就是 \((1111111)_2=127\),所以合起来,8位原码最小的就是-127,选A。
第2题
反码表示中,零的表示形式有:
A.1种
B.2种
C.8种
D.16种
【答案】:B
【解析】
在反码表示中,零有两种表示形式:+0(全0)和-0(全1))。
第3题
补码 1011 1011 对应的真值是( )
A.-69
B.-59
C.-68
D.-58
【答案】:A
【解析】
补码10111011最高位为1,表示负数。求真值可以将其符号位不变,其余各位依次取反再加1,得到\((11000101)_2=(-69)_{10}\),所以答案为A。
第4题
若X的8位补码为 0000 1010,则 X/2 的补码是( )。
A.0000 0101
B.1000 0101
C.0000 0101 或 1000 0101
D.算术右移后结果取决于符号位
【答案】:A
【解析】
方法1:00001010转为十进制为10,X/2=5,补码为00000101。
方法2:除以2相当于是右移1位。在补码表示中,正数右移1位时,高位补0;负数右移1位时,高位补1。此处Ⅹ为正数,故X/2的补码为00000101。
第5题
二进制数 1101.101 对应的十进制数是( )
A.13.625
B.12.75
C.11.875
D.14.5
【答案】:A
【解析】
将二进制数1101.101转换为十进制:\(1101.101=1×2^3+1×2^2+0×2^1+1×2^0+1×2^{-1}+0×2^{-2}+1×2^{-3}=8+4+0+1+0.5+0+0.125\)
第6题
补码加法中,若最高位和次高位进位不同,则说明( )
A.结果正确
B.发生上溢
C.发生下溢
D.结果符号位错误
【答案】:B
【解析】
两个非负数相加变成负数的情况。这种情况一般称为“上溢”。
第7题
八进制数 35.6 对应的十进制数是( )
A.29.75
B.28.5
C.27.625
D.30.25
【答案】:A
【解析】
将八进制数35.6转换为十进制:\((35.6)_8=3×8^1+5×8^0+6×8^{-1}=24+5+6\div 8=29+0.75=29.75\)
因此答案为A。
第8题
二进制数 1010 | 1100 的结果是( )
A.1000
B.1110
C.1010
D.1100
【答案】:B
【解析】
符号"|"表示按位或操作,即只要对应位有一个为1,结果就为1:1010|1100按位进行或运算,结果为1110。答案为B。
第9题
以下哪个位运算可以交换两个变量的值(无需临时变量)( )
A.a = a ^ b; b = a ^ b; a = a ^ b;
B.a = a & b; b = a | b; a = a & b;
C.a = a | b; b = a ^ b; a = a ^ b;
D.a = ~a; b = ~b; a = ~a;
【答案】:A
【解析】
要交换两个变量的值,可以使用异或运算的特性:a ^ a = 0, a ^ 0 = a,且异或运算满足交换律和结合律。因此答案为A。
第10题
如何正确定义一个长度为5的整型数组( )
A.int array = new int[5];
B.array int[5];
C.int[] array = {1,2,3,4,5};
D.int array[5];
【答案】:D
【解析】
在主流编程语言(如C、C++、J Java)中,正确定义长度为5的整型数组的方式是使用类型后跟数组名,然后在方括号中指定长度。选项D "int array[5];"是标准的声明方式,定义了一个名为 array 的5个整数元素的数组。答案为D。
第11题
以下程序使用枚举法(穷举法)求解满足条件的三位数,横线处应该填入的是( )
#include <iostream>
using namespace std;int main() {int count = 0;for (int i=100; i<=999; i++) {int a = i / 100;______int c = i % 10;if (a * a + b * b == c * c) {count++;}}cout << count << endl;return 0;
}
A.int b = (i / 10) / 10;
B.int b = (i / 10) % 10;
C.int b = (i % 10) / 10;
D.int b = (i % 10) % 10;
【答案】:B
【解析】
程序在寻找满足\(a^2+b²=c²\)的三位数。已知 a=i/100(百位),c=i%10(个位),所以b应为十位数,即(i%100)/10或(i/10)%10。在这些选项中, "int b=(i/10)%10;"正确提取了十位数字。答案为B。
第12题
以下程序模拟了一个简单的小球反弹过程,横线处应该填入的是( )
#include <iostream>
using namespace std;int main() {int height = 10;int distance = 0;for (int i=1; i<=5; i++) { // 模拟5次落地______height /= 2;distance += height;}cout << distance << endl;return 0;
}
A.distance += height/2;
B.distance += height;
C.distance += height*2;
D.distance += height+1;
【答案】:B
【解析】
程序模拟小球反弹过程,每次弹起高度为上次的一半(height/=2)。总距离应包含下落距离和上升距离。第9行是高度减半,减半完应为反弹的高度,第10行则累加了反弹得上升距离。所以由此可知,程序目前还缺累加下落距离,应填在第8行。由于第8行时高度还未减半,所以直接累加即可(下落高度是原高度,反弹高度是当次下落高度的一半)。所以答案选B。
第13题
C++代码 string s = "GESP考试"; ,s占据的字节数是( )
A.10
B.8
C.8或10
D.取决于计算机采用什么编码
【答案】:B
【解析】
在C++中,汉字采用不同的编码方案所得到的字节数不同。
第14题
C++语句 string s="Gesp Test"; 执行s.rfind("e")以后,输出的是( )
A.1
B.2
C.6
D.3
【答案】:C
【解析】
string 的rfind()方法从右向左查找字符,返回找到的字符下标。"Gesp Test"中,从右向左第一个"e"出现在"Test"中,下标为6(从0开始),因此答案为C。
第15题
字符串"Gesp考试",字符数是( )
A.10
B.8
C.6
D.字符数多少取决于编码
【答案】:C
【解析】
字符串"Gesp考试"包含6个字符:G、e、s、p、考、试。
判断题
第16题
C++中 string 的 == 运算符比较的是字符串的内存地址,而非内容
A.正确
B.错误
【答案】:B
【解析】
string类型变量进行 == 比较时,比较的是内容,只有字符串字面量进行比较时,才比较地址面非内容
第17题
string 的 substr(1, 3) 返回从下标1开始的3个字符的子串。
A.正确
B.错误
【答案】:A
【解析】
string 的 substr(pos, len)函数返回从 pos 位置开始、长度为 len 的子字符串。substr(1, 3)表示从索引1(第二个字符)开始,提取长度为3的子串。例如,对于字符串"Hello",substr(1, 3)将返回"ell"。
第18题
x 是浮点数, (x >> 1) 等价于 x / 2
A.正确
B.错误
【答案】:B
【解析】
位运算只能针对整数类型进行运算。
第19题
string("hello") == "hello" 的比较结果为true。
A.正确
B.错误
【答案】:A
【解析】
string类型进行 == 比较时,比较的是内容。所以题面描述正确。
第20题
sort 可以直接用于排序 set 中的元素。
A.正确
B.错误
【答案】:B
【解析】
set不可以用 sort 排序。
第21题
(x & 1) == 0 可以判断整数 x 是否为偶数。
A.正确
B.错误
【答案】:A
【解析】
本质为取出x二进制的最低位进行判断,偶数的二进制形式中最低位一定为0。
第22题
string 的 substr(2, 10) 在字符串长度不足时会抛出异常。
A.正确
B.错误
【答案】:B
【解析】
当字符串长度不足时,不会抛出异常,会截取到最后一个字符。
第23题
在数学纸面计算中, pow(2, 3) 的计算结果一定是8,但是在C++中,如果遇到数据类型是浮点数,那就不 一定正确。
A.正确
B.错误
【答案】:A
【解析】
计算机无法精确表示所有小数。
第24题
在 C++ 中,枚举的底层类型可以是非整型(如 float 或 double )。
A.正确
B.错误
【答案】:B
【解析】
必须是整型。
第25题
函数声明 double f(); 返回 int 时,会自动转换为 double
A.正确
B.错误
【答案】:A
【解析】
这里有一个自动地隐式类型转换。
编程题
B4358 奇偶校验
【题目来源】
洛谷:B4358 [GESP202506 三级] 奇偶校验 - 洛谷
【题目描述】
数据在传输过程中可能出错,因此接收方收到数据后通常会校验传输的数据是否正确,奇偶校验是经典的校验方式之一。
给定 \(n\) 个非负整数 \(c_1,c_2,…,c_n\) 代表所传输的数据,它们的校验码取决于这些整数在二进制下 \(1\) 的数量之和的奇偶性。如果这些整数在二进制下共有奇数个 \(1\),那么校验码为 \(1\);否则校验码为 \(0\)。你能求出这些整数的校验码吗?
【输入】
第一行,一个正整数 \(n\),表示所传输的数据量。
第二行,\(n\) 个非负整数 \(c_1,c_2,…,c_n\),表示所传输的数据。
【输出】
输出一行,两个整数,以一个空格分隔:
第一个整数表示 \(c_1,c_2,…,c_n\) 在二进制下 \(1\) 的总数量;
第二个整数表示校验码(\(0\) 或 \(1\))。
【输入样例】
4
71 69 83 80
【输出样例】
13 1
【算法标签】
《洛谷 B4358 奇偶校验》 #进制# #循环结构# #GESP# #2025#
【代码详解】
#include <bits/stdc++.h>
using namespace std;const int N = 105; // 定义数组最大长度int n; // 输入的数字个数
int ans = 0; // 存储所有数字二进制中1的总个数
int a[N]; // 存储输入的数字数组// 计算数字x的二进制表示中1的个数
int cal(int x)
{int res = 0; // 计数器,记录1的个数// 循环处理每一位while (x){// 检查最低位是否为1if (x & 1 == 1)res++;// 右移一位,处理下一位x >>= 1;}return res;
}int main()
{cin >> n; // 输入数字个数// 输入n个数字for (int i = 1; i <= n; i++)cin >> a[i];// 计算所有数字二进制中1的总个数for (int i = 1; i <= n; i++)ans += cal(a[i]);// 输出总1的个数和其奇偶性cout << ans << " ";// 判断总1个数的奇偶性if (ans % 2 == 0)cout << 0 << endl; // 偶数输出0elsecout << 1 << endl; // 奇数输出1return 0;
}
【运行结果】
4
71 69 83 80
13 1
B4359 分糖果
【题目来源】
洛谷:B4359 [GESP202506 三级] 分糖果 - 洛谷
【题目描述】
有 \(n\) 位小朋友排成一队等待老师分糖果。第 \(i\) 位小朋友想要至少 \(a_i\) 颗糖果,并且分给他的糖果数量必须比分给前一位小朋友的糖果数量更多,不然他就会不开心。
老师想知道至少需要准备多少颗糖果才能让所有小朋友都开心。你能帮帮老师吗?
【输入】
第一行,一个正整数 \(n\),表示小朋友的人数。
第二行,\(n\) 个正整数 \(a_1,a_2,…,a_n\),依次表示每位小朋友至少需要的糖果数量。
【输出】
输出一行,一个整数,表示最少需要准备的糖果数量。
【输入样例】
4
1 4 3 3
【输出样例】
16
【算法标签】
《洛谷 B4359 分糖果》 #贪心# #数组# #GESP# #2025#
【代码详解】
#include <bits/stdc++.h>
using namespace std;#define int long long // 定义int为long long类型
const int N = 1005; // 定义数组最大长度int n; // 输入的数字个数
int a[N]; // 存储原始数字数组
int s[N]; // 存储处理后的数字数组
int ans = 0; // 存储最终结果signed main()
{// 输入数字个数cin >> n;// 输入n个数字for (int i = 1; i <= n; i++)cin >> a[i];// 处理数组,确保s[i]至少比前一个大1for (int i = 1; i <= n; i++)s[i] = max(a[i], s[i - 1] + 1);// 计算处理后数组的总和for (int i = 1; i <= n; i++){ans += s[i];}// 输出最终结果cout << ans << endl;return 0;
}
【运行结果】
4
1 4 3 3
16