#TK1161. 2025年3月CCF-GESP编程能力等级认证C++编程七级真题

2025年3月CCF-GESP编程能力等级认证C++编程七级真题

2025年3月CCF-GESP编程能力等级认证C++编程七级真题

一、单选题(每题 2 分,共 30 分)

第 1 题 下列哪个选项是C++中的关键字?
{{ select(1) }}

  • function
  • class
  • method
  • object

第 2 题 下面代码输出的是()

int main() { 
  int a = 10; 
  int *p = &a; 
  int *&q = p; 
  *q = 20; 
  cout << a << endl; 
  return 0; 
}

{{ select(2) }}

  • 1
  • 2
  • 5
  • 10

第 3 题 以下代码的输出是什么?

int main() { 
  int a = 5, b = 2; 
  cout << (a >> b) << endl; 
}

{{ select(3) }}

  • 10
  • 20
  • 地址值
  • 编译错误

第 4 题 下面代码输出的是()

int main() { 
  int arr[5] = {1, 2, 3, 4, 5}; 
  int *p = arr + 2; 
  cout << *p << endl; 
  return 0; 
}

{{ select(4) }}

  • 1
  • 2
  • 3
  • 4

第 5 题 下列关于排序的说法,正确的是( )。
{{ select(5) }}

  • 选择排序是最快的排序算法之一。
  • 归并排序通常是稳定的。
  • 最差情况,( n )个元素做快速排序的时间复杂度为 ( O(n^2) )。
  • 最好情况,( n )个元素做插入排序的时间复杂度为 ( O(n) )。

第 6 题 下面关于C++类构造和析构函数的说法,错误的是( )。
{{ select(6) }}

  • 构造函数不能声明为虚函数。
  • 析构函数必须声明为虚函数。
  • 类的默认构造函数可以被声明为private。
  • 类的析构函数可以被声明为private。

第 7 题 下列关于树和图的说法,错误的是( )。
{{ select(7) }}

  • 树是一种有向无环图,但有向无环图不都是一棵树。
  • 如果把树看做有向图,每个节点指向其子节点,则该图是强连通图。
  • ( n )个顶点且连通的无向图,其最小生成树一定包含 ( n-1 )条边。
  • ( n )个顶点、( n-1 )条边的有向图,一定不是强连通的。

第 8 题 ( 8 ) 是个神奇的数字,因为它是由两个数 ( 2 ) 和 ( 2 ) 拼接而成,而且 ( 2^2 + 2^2 = 8 )。小杨决定写个程序找找小于 ( N ) 的正整数中共有多少这样神奇的数字。下面程序横线处应填入的是( )。

#include <string> 
int count_miracle(int N) { 
  int cnt = 0; 
  for (int n = 1; n * n < N; n++) { 
    int n2 = n * n; 
    std::string s = std::to_string(n2); 
    for (int i = 1; i < s.length(); i++) {
      if (s[i] != '0') { 
        std::string sl = s.substr(0, i); 
        std::string sr = s.substr(i); 
        int nl = std::stoi(sl); 
        int nr = std::stoi(sr); 
        if (_________) // 在此处填入选项
          cnt++; 
      } 
    } 
  } 
  return cnt; 
}

{{ select(8) }}

  • nl + nr == n
  • nl + nr == n2
  • (nl + nr) * (nl + nr) == n
  • (nl + nr) ^ 2 == n2

第 9 题 给定一个无向图,图的节点编号从 ( 0 ) 到 ( n-1 ),图的边以邻接表的形式给出。下面的程序使用深度优先搜索(DFS)遍历该图,并输出遍历的节点顺序。横线处应该填入的是()

#include <iostream> 
#include <vector> 
#include <stack> 
using namespace std;
void DFS(int start, vector<vector<int>>& graph, vector<bool>& visited) { 
  stack<int> s;
  s.push(start); 
  visited[start] = true;
  while (!s.empty()) { 
    int node = s.top(); 
    s.pop(); 
    cout << node << " "; // 输出当前节点
    // 遍历邻接节点 
    for (int neighbor : graph[node]) { 
      if (!visited[neighbor]) {
        __________________ __________________
      } 
    } 
  } 
}

{{ select(9) }}

  • visited[neighbor] = true; s.push(neighbor-1);
  • visited[neighbor] = true; s.push(neighbor+1);
  • visited[neighbor] = false; s.push(neighbor);
  • visited[neighbor] = true; s.push(neighbor);

第 10 题 给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。下面的程序横线处应该填入的是()

#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std;
int lengthOfLIS(vector<int>& nums) { 
  int n = nums.size(); 
  if (n == 0) return 0; 
  vector<int> dp(n, 1);
  for (int i = 1; i < n; i++) { 
    for (int j = 0; j < i; j++) { 
      if (nums[i] > nums[j]) { 
        _________________________ 
      } 
    } 
  } 
  return *max_element(dp.begin(), dp.end()); 
}

{{ select(10) }}

  • dp[i] = max(dp[i], dp[j]);
  • dp[i] = max(dp[i+1], dp[j] + 1);
  • dp[i] = max(dp[i], dp[j] - 1);
  • dp[i] = max(dp[i], dp[j] + 1);

第 11 题 给定一个整数数组 nums,找到其中最长的严格上升子序列的长度。子序列是指从原数组中删除一些元素(或不删除)后,剩余元素保持原有顺序的序列。该程序的时间复杂度为()
{{ select(11) }}

  • ( O(n) )
  • ( O(n \log n) )
  • ( O(n^2) )
  • ( O(2^n) )

第 12 题 给定两个无向图 ( G1 ) 和 ( G2 ),判断它们是否同构。图的同构是指两个图的节点可以通过某种重新编号的方式完全匹配,且边的连接关系一致。为了简化问题,假设图的节点编号从 ( 0 ) 到 ( n-1 ),并且图的边以邻接表的形式给出。下面程序中横线处应该给出的是()

#include <iostream> 
#include <vector> 
#include <map> 
#include <algorithm> 
using namespace std;
string graphHash(vector<vector<int>>& graph) { 
  vector<string> nodeHashes(graph.size());
  for (int i = 0; i < graph.size(); i++) { 
    vector<int> neighbors = graph[i]; 
    sort(neighbors.begin(), neighbors.end()); 
    string hash; 
    for (int neighbor : neighbors) { 
      —————————————————————————— 
    } 
    nodeHashes[i] = hash; 
  } 
  sort(nodeHashes.begin(), nodeHashes.end()); 
  string finalHash;
  for (string h : nodeHashes) { 
    finalHash += h + ";"; 
  } 
  return finalHash; 
}

{{ select(12) }}

  • hash += to_string(neighbor);
  • hash += to_string(neighbors);
  • hash += to_string(neighbor) + ",";
  • hash -= to_string(neighbors);

第 13 题 给定一个 ( m \times n ) 的二维网格 grid,每个格子中有一个非负整数。请找出一条从左上角 ( (0, 0) ) 到右下角 ( (m-1, n-1) ) 的路径,使得路径上的数字总和最小。每次只能向右或向下移动。横线处应该填入的是()

#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std;
int minPathSum(vector<vector<int>>& grid) {
  int m = grid.size(); 
  int n = grid[0].size();
  vector<vector<int>> dp(m, vector<int>(n, 0));
  dp[0][0] = grid[0][0]; 
  for (int j = 1; j < n; j++) { 
    dp[0][j] = dp[0][j - 1] + grid[0][j]; 
  } 
  for (int i = 1; i < m; i++) { 
    dp[i][0] = dp[i - 1][0] + grid[i][0];
  } 
  for (int i = 1; i < m; i++) { 
    for (int j = 1; j < n; j++) { 
      ———————————————————————————————— 
    } 
  } 
  return dp[m - 1][n - 1]; 
}

{{ select(13) }}

  • dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][1];
  • dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
  • dp[i][j] = min(dp[i - 1][j], dp[i][j]) + grid[i][j];
  • dp[i][j] = min(dp[i][j], dp[i][j - 1]) + grid[i][j];

第 14 题 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。下面横线处应该填入的是()

#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std;
int maxSubArray(vector<int>& nums) { 
  int n = nums.size(); 
  if (n == 0) return 0;
  vector<int> dp(n, 0);
  dp[0] = nums[0]; 
  int maxSum = dp[0];
  for (int i = 1; i < n; i++) { 
    _____________________________________
    maxSum = max(maxSum, dp[i]); 
  } 
  return maxSum; 
}

{{ select(14) }}

  • dp[i] = max(nums[i+1], dp[i - 1] + nums[i]);
  • dp[i] = max(nums[i], dp[i - 1] + nums[i]);
  • dp[i] = max(nums[i], dp[i + 1] + nums[i]);
  • dp[i] = max(nums[i], dp[i - 1] + nums[i+1]);

第 15 题 在哈希表的实现中,冲突解决是一个重要的问题。以下哪种方法不是常见的哈希表冲突解决策略?
{{ select(15) }}

  • 链地址法(Chaining)
  • 开放地址法(Open Addressing)
  • 二次哈希法(Double Hashing)
  • 二分查找法(Binary Search)

二、判断题(每题 2 分,共 20 分)

第 1 题 在C++语法中,表达式 1e6100000010^6 的值是相同的。( )
{{ select(16) }}

第 2 题 在C++语言中,函数调用前必须有函数声明或定义。( )
{{ select(17) }}

第 3 题 快速排序一般是不稳定的。( )
{{ select(18) }}

第 4 题 long long 类型能表达的数都能使用 double 类型精确表达。( )
{{ select(19) }}

第 5 题 使用 math.hcmath 头文件中的函数,表达式 cos(60) 的结果类型为 double、值约为 0.5。( )
{{ select(20) }}

第 6 题 一颗 ( h ) 层的满二叉树,一定有 ( 2^h - 1 ) 个结点。( )
{{ select(21) }}

第 7 题 邻接表和邻接矩阵都是图的存储形式。为了操作时间复杂度考虑,同一个图可以同时维护两种存储形式。( )
{{ select(22) }}

第 8 题 子类对象包含父类的所有成员(包括私有成员)。从父类继承的私有成员也是子类的成员,因此子类可以直接访问。( )
{{ select(23) }}

第 9 题 动态规划算法通常有递归实现和递推实现。但由于递归调用在运行时会由于层数过多导致程序崩溃,有些动态规划算法只能用递推实现。( )
{{ select(24) }}

第 10 题 按照下面的规则生成一棵二叉树:以一个人为根节点,其父亲为左子节点,母亲为右子节点。对其父亲、母亲分别用同样规则生成左子树和右子树。以此类推,记录30代的直系家谱,则这是一棵满二叉树。( )
{{ select(25) }}

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

3.1 编程题 1
题目名称:图上移动
时间限制:1.0 s
内存限制:512.0 MB
题目描述: 小 A 有一张包含 ( n ) 个结点与 (