Bootstrap

2024年GESP12月认证C++三级真题解析

GESP 三级

第 1 题

题目: 下列⼆进制表⽰的⼗进制数值分别是( B )

  • [10000011]原=( )
  • [10000011]补=( )

选项:
A. -125,-3
B. -3, -125
C. -3,-3
D. -125,-125

答案: B

解析:

  • 原码:最高位为符号位,1表示负数,其余位表示数值。[10000011]原 = -3。
  • 补码:负数的补码是其原码除符号位外取反加1。[10000011]补 = -125。
第 2 题

题目: 关于计算机中的编码,下列说法中错误的是(D)

选项:
A. 对于⽆符号数,原码就是真值
B. 正数的反码是其本⾝
C. 负数的反码和补码是不⼀样的
D. 负数的反码,在其原码的基础上, 各个位取反

答案: D

解析:

  • A:正确,无符号数的原码就是其真值。
  • B:正确,正数的反码和原码相同。
  • C:正确,负数的反码和补码不同。
  • D:错误,负数的反码是在其原码的基础上,符号位不变,其余位取反。
第 3 题

题目: 16进制数B2025转换成8进制数是(A)

选项:
A. 2620045
B. 2004526
C. 729125
D. 2420045

答案: A

解析:

  • 先将16进制数B2025转换为二进制:1011 0010 0000 0010 0101。
  • 再将二进制数转换为8进制:101 100 100 000 001 001 010 → 2620045。
第 4 题

题目: 625.625变成⼆进制是( A )。

选项:
A. 1001110001.101
B. 101.101
C. 101.1001110001
D. 1001110001.1101

答案: A

解析:

  • 625.625的整数部分625转换为二进制是1001110001。
  • 小数部分0.625转换为二进制是0.101。
  • 因此,625.625的二进制表示是1001110001.101。
第 5 题

题目: 下⾯逻辑运算中,正确的是(D )

选项:
A. 5&&3==0
B. 5|3==8
C. 5||3==11
D. 5&3==0001

答案: D

解析:

  • A:错误,5&&3的结果是1,不是0。
  • B:错误,5|3的结果是7,不是8。
  • C:错误,5||3的结果是1,不是11。
  • D:正确,5&3的结果是1,二进制表示为0001。
第 6 题

题目: 补码1111 1101进行运算1111 1101>>1以后得到的结果是(B)

选项:
A. 1111 1100
B. -2
C. 1111 1101
D. 1111 1010

答案: B

解析:

  • 补码1111 1101表示的十进制数是-3。
  • 右移1位后,结果是1111 1100,表示的十进制数是-2。
第 7 题

题目: 下列代码输出的是 A

string s="1234@@chenadai";
string str="12345";
s.replace(1,5,str);
cout<<str<<endl;

选项:
A. 12345
B. 2345@
C. 112345chenadai
D. 12345chenadai

答案: A

解析:

  • s.replace(1,5,str);s从第1个字符开始的5个字符替换为str,但str本身没有改变。
  • 最后输出的是str,即"12345"。
第 8 题

题目: a|10(a与10都是10进制,且二进制表示最高位为1)运算的结果是( )。

选项:
A. 使a的二进制表示从右往左的第二位为1
B. 使a的二进制表示从右往左的第一位为0
C. 使a的二进制表示从右往左第二位为0
D. 使a的二进制表示最高位为0

答案: A

解析:

  • a|10 的二进制运算会将a的第二位设置为1,因为10的二进制是1010。
第 9 题

题目: 下列程序输出的是( )

string ch="hello";
if(ch[5]==NULL)
{
    cout<<"right"<<endl;
}
else if (ch[5]=='\0')
{
    cout<<"wrong"<<endl;
}
else
{
    cout<<"hello"<<endl;
}

选项:
A. right
B. wrong
C. hello
D. 不能正确执行

答案: A

解析:

  • ch[5] 是字符串的无效索引位置,所以式NULL。
第 10 题

题目: 下列程序中,假设一个字符占用的内存空间是1,下列程序中,ch占用的内存空间是 ( D)

char ch[] = "hello world";
size_t ret=strlen(ch);
cout<<ret<<endl;

选项:
A. 11
B. 10
C. 13
D. 12

答案: D

解析:

  • ch占用空间包含结束符‘\n’,所以是11
第 11 题

题目: 下列程序最后输出的是(D)

int a=65;
cout<<tolower(a)<<endl;

选项:
A. 65
B. A
C. a
D. 97

答案: D

解析:

  • tolower(a) 将大写字母A(65)转换为小写字母a(97),返回值是整数类型。
  • 所以输出的是数字97。
第 12 题

题目: 想要计算从数字n到数字m之间(包含n和m)有多少个数字d出现,下列程序哪个能够实现( )。

选项:
A.

int n,m,res,d;
cin >> n >> m>>d;
for(int i = n+1; i <= m; i++){
    int temp = i;
    while(temp){
        if(temp % 10 == d) res++;
        temp /= 10;
    }
}
cout << res << endl;
return 0;

B.

int n,m,res,d;
cin >> n >> m>>d;
for(int i = n; i <= m; i++){
    int temp = i;
    while(temp){
        if(temp % 10 = d) res++;
        temp /= 10;
    }
}
cout << res << endl;
return 0;

C.

int n,m,res=0,d;
cin >> n >> m>>d;
for(int i = n; i <= m; i++){
    int temp = i;
    while(temp){
        if(temp % 10 == d) res++;
        temp /= 10;
    }
}
cout << res << endl;
return 0;

D.

int n,m,res=0,d;
cin >> n >> m>>d;
for(int i = n; i <= m; i++){
    while(temp){
        if(temp % 10 == d) res++;
        temp /= 10;
    }
}
cout << res << endl;
return 0;

答案: C

解析:

  • 选项C正确实现了从n到m之间数字d出现的次数统计。
  • 选项A错误,因为in+1开始,漏掉了n
  • 选项B错误,因为if(temp % 10 = d)应该是==而不是=
  • 选项D错误,因为while(temp)中的temp未定义。
第 13 题

题目: 兔⼦五元⼀只,鸡三元⼀只,⼩鸭⼦⼀元三只,现在你有⼀百元要买⼀百只,兔⼦、鸡、鸭⼦,问兔⼦、鸡、鸭⼦各买多少只,每种必须⾄少⼀只,下列哪个程序能实现。( )。

选项:
A.

for(int i = 0; i <= 100; i++){
    for(int j = 0; j <= 100; j++){
        for(int k = 0; k <= 100; k++){
            if(i + j + k == 100 && 25 * i + 10 * j + k == 300)
                cout << i << " " << j << " " << k << endl;
        }
    }
}

B.

for(int i = 0; i <= 100; i++){
    for(int j = 0; j <= 100; j++){
        for(int k = 0; k <= 100; k++){
            if(i + j + k == 100 && 20 * i + 10 * j + k == 300)
                cout << i << " " << j << " " << k << endl;
        }
    }
}

C.

for(int i = 0; i <= 20; i++){
    for(int j = 0; j <= 34; j++){
        for(int k = 0; k <= 20; k++){
            if(i + j + k == 100 && 15 * i + 9 * j + k == 300)
                cout << i << " " << j << " " << k << endl;
        }
    }
}

D.

for(int i = 0; i <= 100; i++){
    for(int j = 0; j <= 100; j++){
        for(int k = 0; k <= 100; k++){
            if(i + j + k == 100 && 15 * i + 9 * j + k == 300)
                cout << i << " " << j << " " << k << endl;
        }
    }
}

答案: D

解析:

  • 选项D正确实现了题目要求,计算了兔⼦、鸡、鸭⼦的数量。
  • 选项A、B、C的计算公式有误。
第 14 题

题目: 求⼩于等于N的素数的⽅法中,有⼀种⽅法是将所有从2到它本⾝减1的数都除⼀遍,如果不能整除,就是素数。下列哪个程序,体现了这种⽅法()

选项:
A.

if(N >= 3){
cout<<2<<endl;
for(int i = 2;i <= N;i ++){
    for(int j = 2;j < i;j ++){
        if(i % j != 0){
            flag = 1;
        }
    }
    if(flag == 0){
        cout<<i<<endl;
    }
    flag = 0;
    }
}

B.

if(N >= 2){
for(int i = 3;i <= N;i ++){
    for(int j = 2;j < i;j ++){
        if(i % j == 0){
            flag = 1;
        }
    }
    if(flag == 0){
        cout<<i<<endl;
    }
    flag = 0;
    }
}

C.

if(N >= 2){
cout<<2<<endl;
for(int i = 3;i <= N;i ++){
    for(int j = 2;j < i;j ++){
        if(i % j == 0){
            flag = 1;
        }
    }
    if(flag == 0){
        cout<<i<<endl;
    }
    flag = 0;
    }
}

D.

if(N >= 2){
    cout<<2<<endl;
    for(int i = 3;i <= N;i ++){
        for(int j = 2;j < i;j ++){
            if(i % j == 0){
                flag = 1;
            }
        }
        if(flag == 0){
            cout<<i<<endl;
        }
    }
}

答案: C

解析:

  • 选项C正确实现了题目要求,先输出2,然后从3开始判断每个数是否为素数。
  • 选项A、B、D的逻辑有误。
第 15 题

题目: 工人工作一天,会得到一个金环作为工资报酬,某个工作需要15天完成,一条15个环的金环项链,为了严格执行每天工作结束时,完成对工人工资的结算,最少需要将金环项链剪裁成几段,每段几个金环( )

选项:
A. 4段,分别是1、2,4,8
B. 15段,每段1个
C. 6段,分别是3、3、3、3、2、1
D. 9段,分别是2、2、2、2、2、2、1、1、1

答案: A

解析:

  • 最少需要剪裁成4段,分别是1、2、4、8,这样可以组合出1到15的所有数字。

GESP 三级

第1题

题目: 为了简化计算机基本运算电路,使加减法都只需要通过加法电路实现,也就是说让减去一个正数或加上一个负数这样的运算可以用加上一个正数来代替。于是改变负数存储的形式,存储成一种可以直接当成正数来相加的形式,这种形式就是补码。

解析:

  • 正确,补码的设计目的是为了简化加减法运算。

答案:

第2题

题目: 使用原码进行的计算,2+(-1)的结果是-3

解析:

  • 正确,先转换成原码,然后进行+计算,结果是-3。

答案:

第3题

题目: 反码计算加减法:加法与减法结果都是正确的,只是解决不了-0的问题

解析:

  • 正确,反码计算加减法的结果是正确的,但存在-0的问题。

答案:

第4题

题目: 10进制数63,在转换成二进制的计算过程中,产生了如下的式子:

163/2=31 余 1
231/2=15 余 1
315/2=7 余 1
47/2=3 余 1
53/2=1 余 1
61/2=0 余 1

按照从前往后的顺序,获得63的二进制值是111111

解析:

  • 错误,按照二进制转换规则,应该按照从后往前的顺序。

答案: ×

第5题

题目: 下列程序输出的是A

char x=65;
x=x&00001111;
cout<<x<<endl;

解析:

  • 正确,
  1. 初始化 x

    char x = 65;
    
    • char 类型的 x 被赋值为 65,在 ASCII 表中,65 对应字符 'A'
    • 二进制表示为:01000001
  2. 按位与操作:

    x = x & 00001111;
    
    • 00001111 这个数字在 C++ 中是一个 八进制 字面量(因为以 0 开头)。
    • 00001111 解释为八进制:
    • 因此,x & 585 的运算等价于 65 & 585
  3. 计算按位与结果:

    • 65585 转换为二进制:
      • 65 的二进制表示(8 位):01000001
      • 585 的二进制表示(至少 10 位):1001001001
    • 为了进行按位与操作,C++ 会将 char 类型的 x 提升为 int 类型:
      • 65 的二进制(扩展为 32 位):00000000 00000000 00000000 01000001
      • 585 的二进制(扩展为 32 位):00000000 00000000 00100100 1001001
    • 因此,x 的新值仍然是 65,对应字符 'A'
  4. 输出结果:

    cout << x << endl;
    
    • xchar 类型,值为 65,因此 cout 会输出字符 'A'
  • 八进制字面量: 在 C++ 中,以 0 开头的数字被解释为八进制。例如,00001111 被视为八进制的 01111,即十进制的 585
  • 位操作中的类型提升: 在进行位操作时,char 类型会被提升为 int 类型,这影响了操作的结果。

答案:

第6题

题目: 下列可执行程序段中,最后 pos 的值是 4

string str="chenADai";
int pos = str.find('D');
--pos&11;

解析:

  • 正确,str.find('D')返回4,--pos&11的结果是4。

答案:

第7题

题目:

string ch="chen";
cout<<ch[4]<<endl;

该段程序将不能正确执行

解析:

  • 错误,可以正常执行。

答案: ×

第8题

题目:

char a='A';
a=a+32;
cout<<(int)a<<endl;

将输出 97

解析:

  • 正确,a='A'的ASCII码是65,a+32的结果是97。

答案:

第9题

题目: 自然界中,最小的素数是 2

解析:

  • 正确,2是最小的素数。

答案:

第10题

题目: CCF(十六进制)=12363(七进制)

解析:

  • 正确,CCF的十六进制表示为12363的七进制表示。

答案:

3. 编程题(每题 25 分,共 50 分)

3.1 编程题 1

题目: 数字替换

时间限制: 1.0 s

内存限制: 512.0 MB

3.1.1 题面描述

小杨有一个包含 n 个数字的序列 A,即 ( A = {a_1, a_2, \ldots, a_n} ),他想将其中大于 k 的数字都替换为序列的最大值,将其中小于 k 的数字都替换为序列的最小值,请你帮他计算出替换后的序列。

3.1.2 输入格式

第一行包含两个正整数 ( n, k ),含义如题面所示。

第二行包含 n 个数字,代表序列 A。

3.1.3 输出格式

输出 n 个整数,代表替换后的结果。

3.1.4 样例

输入:

5 1
-2 -1 0 1 2

输出:

-2 -2 -2 1 1
3.1.5 参考程序
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int a[100010];
int main() {
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    int max_value = a[1], min_value = a[1];
    for (int i = 1; i <= n; i++) {
        max_value = max(max_value, a[i]);
        min_value = min(min_value, a[i]);
    }
    for (int i = 1; i <= n; i++) {
        if (a[i] > k) {
            a[i] = max_value;
        } else if (a[i] < k) {
            a[i] = min_value;
        }
        if (i != n) {
            cout << a[i] << " ";
        } else {
            cout << a[i] << endl;
        }
    }
    return 0;
}
3.2 编程题 2

题目: 打印数字

时间限制: 1.0 s

内存限制: 512.0 MB

3.2.1 题面描述

小杨为数字 0, 1, 2 和 3 设计了一款表示形式,每个数字占用了 ( 5 \times 5 ) 的网格。数字 0, 1, 2 和 3 的表示形式如下:

0:
.....
.***.
.*.*.
.***.
.....

1:
****.
.....
.....
.....
.....

2:
.....
****.
.....
.****
.....

3:
.....
****.
.....
****.
.....

小杨想请你将给定的数字 ( n ) 转换为对应的表示形式。

3.2.2 输入格式

第一行包含一个正整数代表 ( n )。

3.2.3 输出格式

输出对应的表示形式。

3.2.4 样例

输入:

12230

输出:

****.....................
****.****.****.****..***.
****.................***.
****..****.********..***.
****.....................
3.2.5 参考程序
#include <iostream>
#include <string>
using namespace std;
int main() {
    string n;
    cin >> n;
    for (int row = 0; row < 5; row++) {
        string line = "";
        for (char digit : n) {
            if (digit == '0') {
                if (row == 0 || row == 4) {
                    line += ".....";
                } else {
                    line += ".***.";
                }
            } else if (digit == '1') {
                line += "****.";
            } else if (digit == '2') {
                if (row == 0) {
                    line += ".....";
                } else if (row == 1) {
                    line += "****.";
                } else if (row == 2) {
                    line += ".....";
                } else if (row == 3) {
                    line += ".****";
                } else {
                    line += ".....";
                }
            } else if (digit == '3') {
                if (row == 0) {
                    line += ".....";
                } else if (row == 1) {
                    line += "****.";
                } else if (row == 2) {
                    line += ".....";
                } else if (row == 3) {
                    line += "****.";
                } else {
                    line += ".....";
                }
            }
        }
        cout << line << endl;
    }
    return 0;
}
;