真题解析 | CCF CSP-J 2020 入门级 C++语言真题及答案

 一、单项选择题(共15题,每题2分,共计30分;每题有且仅有一个正确选项)

解析:常识题。在计算机内存中,每个存储单元都有一个唯一的标识号,这个标识号被称为地址。地址用来唯一标识内存中的每个存储单元,类似于房子的门牌号,可以准确地找到并访问内存中的特定数据。通过地址,计算机可以准确地定位和访问存储单元中的数据,实现数据的读取和写入操作。因此,地址在计算机内存中起着非常重要的作用,确保数据的准确存储和检索。

解析: 常识题。

        编译器是一种将高级语言源代码翻译成机器语言目标代码的程序。它接收程序员编写的高级语言源代码作为输入,经过词法分析、语法分析、语义分析、优化和代码生成等过程,最终生成可被计算机执行的机器指令代码。这样,计算机可以直接执行这些机器指令代码来实现程序的功能。

 

解析: 简单逻辑运算。首先,根据题目给出的条件:

x=true, y=true, z=false。

然后逐个选项计算表达式的值:

A. (y∨z)∧x∧z = (true ∨ false) ∧ true ∧ false = true ∧ true ∧ false = false

B. x∧(z∨y)∧z = true ∧ (false ∨ true) ∧ false = true ∧ true ∧ false = false

C. (x∧y)∧z = (true ∧ true) ∧ false = true ∧ false = false

D. (x∧y)∨(z∨x) = (true ∧ true) ∨ (false ∨ true) = true ∨ true = true

解析: 对图像存储空间的计算,涉及到图像分辨率、位深度和存储空间的关系。

        要存储一张分辨率为2048×1024像素、32位真彩色图像,首先需要计算图像的总像素数,然后根据每个像素的位数计算存储空间。

  1. 计算图像的总像素数:2048×1024=2097152 像素
  2. 每个像素为32位真彩色,即每个像素需要占用32位 = 4字节(1字节=8位)
  3. 计算存储空间: 2097152×4=8388608 字节
  4. 将字节转换为MB: 8388608字节=102428388608​MB≈8MB

解析: 冒泡排序简单考察

        冒泡排序算法的比较次数取决于数组中元素的初始排列顺序。

  •         在最坏情况下,即数组完全逆序时,冒泡排序算法的比较次数为 𝑛(𝑛−1)/2次。
  •         在最好的情况下,即数组已经是按非递减顺序排序好的情况下,冒泡排序算法仍然需要进行𝑛−1次比较。这是因为在每一轮冒泡排序中,虽然不需要进行元素交换,但仍然需要比较相邻元素的大小来确认顺序是否正确。

解析: 递归的简单考察

解析: 链表

        链表是链式存储,需要从头开始遍历读取数据——顺序访问,不可直接读取——随机访问。

解析: 连通图

        用于描述图中顶点之间是否存在路径相连。一个无向图中,如果从图中的任意一个顶点出发,都可以通过边的连接到达图中的任意其他顶点,则该图被称为连通图。

连通图的性质:

  • 连通图中的任意两个顶点之间都存在一条路径。
  • 连通图中的最小生成树是唯一的。
  • 连通图中的边数至少为顶点数减一,否则无法保证所有顶点之间都连通。

解析: 二进制转换

要将二进制数1011转换为十进制数,可以按照以下步骤进行:

1. 从二进制数的最右边开始,从低位到高位,分别对每一位进行计算。
2. 从右向左,第0位是最低位,第n位是最高位,对应的权重为$2^0, 2^1, 2^2, ... , 2^n$。
3. 将每一位的数值乘以对应的权重,然后将所有结果相加即可得到十进制数。

对于二进制数1011:
- 第0位(最右边)为1,对应的权重为$2^0 = 1$,计算结果为$1 \times 2^0 = 1$;
- 第1位为1,对应的权重为$2^1 = 2$,计算结果为$1 \times 2^1 = 2$;
- 第2位为0,对应的权重为$2^2 = 4$,计算结果为$0 \times 2^2 = 0$;
- 第3位为1,对应的权重为$2^3 = 8$,计算结果为$1 \times 2^3 = 8$。

最后,将所有结果相加:$1 + 2 + 0 + 8 = 11$。

因此,二进制数1011转换为十进制数为11。

解析:排列组合

        将双胞胎小朋友看作一个整体,即将两个双胞胎小朋友看作一个人。这样,5个小朋友排成一列的问题就变成了4个小朋友和1对双胞胎小朋友排成一列的问题。 典型的全排列问题 :A(4,4)*A(2,2) = 4! * 2! = 24 x 2 = 48!(四个小朋友全排列 * 两个双胞胎之间互换位置)

解析: 数据结构特性,

         符合先入后出特性,先入在底部,后入在顶部,栈无疑。

  

解析: 完全二叉树

        对于一个完全二叉树,假设其高度为ℎ,则其最少节点数为2^h-1个,最多节点数为2^{h+1}-1个。

        根据题目中给出的信息,独根树的高度为1,即只有一个节点。因此,61个节点的完全二叉树的高度应该在5和6之间。

我们可以通过尝试计算不同高度下的节点数来确定答案:

  • 当高度为5时,节点数范围为25−1=31到26−1=63,不符合61个节点的条件;
  • 当高度为6时,节点数范围为26−1=63到27−1=127,符合61个节点的条件。

解析: 简单数学

        天干:1949%10 = 9(己),地支:1949%12 = 5(丑)

解析: 排列组合

        这个问题是一个经典的分配问题,需要考虑将10个三好学生名额分配到7个班级,每个班级至少有一个名额的情况。

        我们可以使用插板法(Stars and Bars)来解决这个问题。假设我们有10个三好学生名额(星号),需要将它们分配到7个班级(板子)中,每个班级至少有一个名额。

根据插板法的公式,总的分配方案数为 𝐶(𝑛−1,𝑘−1),其中𝑛表示总的名额数,𝑘表示班级数,𝐶表示组合数。

        在这个问题中,𝑛=10,𝑘=7,所以总的分配方案数为 𝐶(10−1,7−1)=𝐶(9,6)。

        

        因此,将10个三好学生名额分配到7个班级,每个班级至少有一个名额的不同分配方案数为84种。

解析:  排列组合

二、阅读程序(程序输入不超过数组或字符串定义的范围:判断题正确填√,错误填×:除特殊说明外,判断题1.5分,选择题3分,共计40分) 

第16题🎈 

#include <cstdlib>
#include <iostream>
using namespace std;

char encoder[26] = {'C','S','P',0};
char decoder[26];

string st;

int main()  {
  int k = 0;
  for (int i = 0; i < 26; ++i)
    if (encoder[i] != 0) ++k;
  for (char x ='A'; x <= 'Z'; ++x) {
    bool flag = true;
    for (int i = 0; i < 26; ++i)
      if (encoder[i] ==x) {
        flag = false;
        break;
      }
      if (flag) {
        encoder[k]= x;
        ++k;
      }
  }
  for (int i = 0; i < 26; ++i)
     decoder[encoder[i]- 'A'] = i + 'A';
  cin >> st;
  for (int i = 0; i < st.length( ); ++i)
    st[i] = decoder[st[i] -'A'];
  cout << st;
  return 0;
}

题目分析: 

  1. 首先定义了两个字符数组 encoder 和 decoder,分别用于加密和解密过程。encoder 数组初始包含三个字符 'C', 'S', 'P',并以0结尾;decoder 数组暂时为空。然后定义了一个字符串 st 用于存储输入的字符串。

  2. 在 main 函数中,首先通过循环计算 k 的值,k 表示 encoder 数组中已有元素的数量。

  3. 接着,通过两层循环遍历字母'A'到'Z',将不在 encoder 数组中的字母依次添加到 encoder 数组中。

  4. 然后,根据 encoder 数组的内容填充 decoder 数组,使得 decoder 数组中的索引与 encoder 数组中的字符对应。

  5. 接下来,程序从标准输入中读取一个字符串,并根据 decoder 数组将字符串中的字符解密为原始字符并输出

•判断题

  1. 输入的字符串应当只由大写字母组成,否则在访问数组时可能越界。( ) 答案与解析: 代码中存在-'A'操作,并且decoder数组大小为26,只有大写字母'A'->'Z',做这样的操作所得值在[0-26]的范围内。
  2. 若输入的字符串不是空串,则输入的字符串与输出的字符串一定不一样。()答案与解析: 错误。
  3. 将第 12 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )答案与解析: 正确。
  4. 将第 26 行的 i < 26 改为 i < 16,程序运行结果不会改变。( )答案与解析: 错误。

•单选题

5) 若输出的字符串为 ABCABCABCAABCABCABCA,则下列说法正确的是( )。

A. 输入的字符串中既有 S 又有 P

 B. 输入的字符串中既有 S 又有 B

 C. 输入的字符串中既有 A 又有 P

 D. 输入的字符串中既有 A 又有 B

 答案与解析: A,

6)若输出的字符串为 CSPCSPCSPCSPCSPCSPCSPCSP,则下列说法正确的是( )。

  A. 输入的字符串中既有 P 又有 K

 B. 输入的字符串中既有 J 又有 R

 C. 输入的字符串中既有 J 又有 K

 D. 输入的字符串中既有 P 又有 R

 答案与解析: D,

第17题

#include <iostream>
using namespace std;

long long n, ans;
int k, len;
long long d[1000000];

int main() {
  cin >> n >> k;
  d[0] = 0;
  len= 1;
  ans = 0;
  for (long long i = 0; i <n; ++i) {
    ++d[0];
    for (int j = 0; j + 1<len; ++j) {
      if (d[j] == k) {
        d[j] = 0;
        d[j + 1] += 1;
        ++ans;
      }
    }
    if (d[len- 1] == k) {
      d[len - 1] = 0;
      d[len] =1;
      ++len;
      ++ans;
    }
  }
  cout << ans << endl;
  return 0;
}

  • 判断题
  1. 若 k=1,则输出 ans 时,len=n。( ) 答案与解析: ×
  2. 若 k>1,则输出 ans 时,len —定小于 nn。( ) 答案与解析:  ×
  3. () 答案与解析:  
  • 单选题

 

解析: 

 

解析:

  

解析: 

第18题

#include <algorithm>
#include <iostream>
using namespace std;                     
                                         
int n;                                   
int d[50][2];                            
int ans;                                 
                                        
void dfs(int n, int sum) {               
  if (n == 1) {                            
    ans = max(sum, ans);           
    return;                                   
  }                                        
  for (int i = 1; i < n; ++i) {            
    int a = d[i - 1][0], b = d[i - 1][1];  
    int x = d[i][0], y = d[i][1];            
    d[i - 1][0] = a + x;                     
    d[i - 1][1] = b + y;                     
    for (int j = i; j < n - 1; ++j)            
      d[j][0] = d[j + 1][0], d[j][1] = d[j + 1][1];
    int s = a + x + abs(b - y);              
    dfs(n - 1, sum + s);                    
    for (int j = n - 1; j > i; --j)          
      d[j][0] = d[j - 1][0], d[j][1] = d[j - 1][1];
    d[i - 1][0] = a, d[i - 1][1] = b;        
    d[i][0] = x, d[i][1] = y;                
  }                                        
}                                        
                                       
int main() {                             
  cin >> n;                                
  for (int i = 0; i < n; ++i)              
  cin >> d[i][0];
  for (int i = 0; i < n;++i)
     cin >> d[i][1];
  ans = 0;
  dfs(n, 0);
  cout << ans << endl;
  return 0;
}

假设输入的 nn 是不超过 5050 的正整数,d[i][0]d[i][1] 都是不超过 1000010000 的正整数,完成下面的判断题和单选题:

  • 判断题

    1. 若输入 nn 为 00,此程序可能会死循环或发生运行错误。( ) 答案与解析:× ,
    2. 若输入 nn 为 2020,接下来的输入全为 00,则输出为 00。( ) 答案与解析:√ ,
    3. 输出的数一定不小于输入的 d[i][0] 和 d[i][1] 的任意一个。( ) 答案与解析:×, 
  • 单选题

    1. 若输入的 nn 为 2020,接下来的输入是 2020 个 99 和 2020 个 00,则输出为( )。,解析:

    2. 若输入的 nn 为 3030,接下来的输入是 3030 个 00 和 3030 个 55,则输出为( )。,解析:

    3. (4 分)若输入的 nn 为 1515,接下来的输入是 1515 到 11,以及 1515 到 11,则输出为( )。,解析:

三、完善程序(单选题,每小题3分,共计30分) 

第19题

#include <cstdio>
using namespace std;
int n, i;

int main() {
  scanf("%d", &n);
  for(i = ①; ② <=n; i ++){
    ③{
      printf("%d ", i);
      n = n / i;
    }
  }
  if(④)
    printf("%d ", ⑤);
  return 0;
}

1)①处应填( ),解析:

2)②处应填( ),解析:

3)③处应填( ),解析:

4)④处应填( ),解析:

5)⑤处应填( ),解析:

 第 20 题

 

#include <iostream>

using namespace std;

const int MAXN = 5000;
int n, m;
struct segment { int a, b; } A[MAXN];

void sort() // 排序
   {
     for (int i = 0; i < n; i++)
     for (int j = 1; j < n; j++)
     if (①)
         {
           segment t = A[j];
           ②
         }
   }

   int main()
   {
     cin >> n >> m;
     for (int i = 0; i < n; i++)
       cin >> A[i].a >> A[i]・b;
     sort();
     int p = 1;
     for (int i = 1; i < n; i++)
       if (③)
         A[p++] = A[i];
     n = p;
     int ans =0, r = 0;
     int q = 0;
     while (r < m)
     {
       while (④)
         q++;
       ⑤;
       ans++;
     }
     cout << ans << endl;
     return 0;
   }

1)①处应填( ),解析:

2)②处应填( ),解析:

3)③处应填( ),解析:

4)④处应填( ),解析:

5)⑤处应填( ),解析:

  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大气层煮月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值