试卷总分:100分
选择题 15题 30分
判断题 10题 20分
编程题 2题 50分
下列代码执行后的输出结果是()。
class Animal { public: virtual void speak() { cout << "Animal "; } virtual ~Animal() = default; }; class Cat : public Animal { public: void speak() override { cout << "Cat "; } }; int main() { Animal *p = new Cat(); p->speak(); delete p ; return 0 ; }
下列代码中,横线处应填写(),才能正确调用基类的带参数构造函数。
class Machine { protected : string id ; public: Machine(string s) : id(s) {} }; class Robot : public Machine { int level; public: Robot(string s , int n) :___________, level(n) {} };
下列代码执行后的输出顺序是()。
class Base { public: Base() { cout << "B "; } virtual ~Base() { cout << "~B "; } }; class Derived : public Base { public: Derived() { cout << "D "; } ~Derived() { cout << "~D "; } }; int main() { Base *p = new Derived(); delete p ; return 0 ; }
stack<int> s ; queue<int> q ; for (int i = 2; i <= 6; i += 2) { s .push(i); q .push(i); } s .pop(); q .pop(); cout << s.top() << " " << q .front();
下面循环队列采用“空出一个位置”的方式区分队空和队满。横线处应填写()。
const int MAXN = 8; int data [MAXN]; int front = 0 , rear = 0 ; bool full() { return __________; }
下列函数实现了二叉树的哪种遍历方式()。
void visit(TreeNode *root) { if (root == nullptr) return ; visit(root->left); cout << root->val << " "; visit(root->right); }
已知一棵二叉树的先序遍历序列为A B D E C F,中序遍历序列为D B E A C F,则其后序遍历序列是()。
下面函数用于计算二叉树的高度,横线处应填写()。
int height(TreeNode *root) { if (root == nullptr) return 0 ; int leftH = height(root->left); int rightH = height(root->right); return ; }
以下代码实现二叉树左子树优先的深度优先搜索算法,则横线上应填写()。
void dfs(TreeNode *root) { if (root == nullptr) return ; stack<TreeNode *> s ; s .push(root); while (!s .empty()) { TreeNode *node = s.top(); s .pop(); cout << node->value << " "; ___________________________ // 在此处填入代码 } }
下面函数在二叉搜索树中查找值x 。横线处应填写()。
TreeNode *searchBST(TreeNode *root , int x) { if (root == nullptr || root->val == x) return root ; if (x < root->val) return searchBST(root->left , x); return _______________________; }
有5个字符,其出现频率分别为2、4、5、9、12。按哈夫曼算法构造编码树,其最小带权路径长度WPL为()。
下面代码用反射法生成n 位格雷编码,横线处应填写()。
vector<string> gray(int n) { vector<string> ans = {"0 ", "1 "}; for (int bit = 2; bit <= n ; ++bit) { int oldSize = ans .size(); for (int i = oldSize - 1; i >= 0 ; --i) ans .push_back( ____________); for (int i = 0 ; i < oldSize ; ++i) ans [i] = "0 " + ans [i]; } return ans ; }
下面代码计算走到第n 级台阶的方法数,每次可以走1 级或2 级。横线处应填写()。
int ways(int n) { if (n <= 2) return n ; vector<int> dp(n + 1); dp [1] = 1; dp [2] = 2; for (int i = 3 ; i <= n ; ++i) dp[i] = _____________; return dp [n]; }
下面代码求从包含非负元素的数组中选择若干个互不相邻元素所能得到的最大和。横线处应填写()。
int maxSum(vector<int> &a) { int n = a .size(); if (n == 0) return 0 ; if (n == 1) return a [0]; vector<int> dp(n); dp [0] = a [0]; dp [1] = max (a [0], a [1]); for (int i = 2; i < n ; ++i) dp[i] = _____________; return dp [n - 1]; }
下面是一维数组实现的0/1 背包。内层循环必须从大到小枚举容量,主要原因是()。
for (int i = 0 ; i < n ; ++i) { for (int w = W; w >= weight [i]; --w) { dp [w] = max (dp [w], dp [w - weight [i]] + value [i]); } }
下列代码可以正常编译,因为编译器会自动为Student 类生成一个无参数构造函数。
class Student { public: Student(int x) { age = x; } private: int age ; }; int main() { Student s ; }
下列代码合法,因为派生类可以直接访问基类的私有成员value。
class Base { private: int value = 10; }; class Child : public Base { public: int get() { return value ; } };
下列代码执行后,输出结果为30。
queue<int> q ; q .push(10); q .push(20); q .push(30); q .pop(); cout << q .front();
一棵完全二叉树按照从上到下、从左到右的顺序,将节点依次存储在数组tree[1]、tree[2]、...... 中。若节点tree[i] 存在左孩子,则其左孩子存储在tree[2 * i] 中。
对任意一棵二叉搜索树执行中序遍历,得到的关键字序列一定是非递减的。
void inorder(TreeNode *root) { if (!root) return ; inorder(root->left); cout << root->val << " "; inorder(root->right); }
若使用下列代码从节点 start 开始访问一棵树,则第一次到达某个节点时所经过的边数,一定是从 start 到该节点的最少边数。
vector<int> tree [100]; bool visited [100]; int dist [100]; void search(int start) { queue<int> q ; q .push(start); visited [start] = true ; dist [start] = 0 ; while (!q .empty()) { int u = q .front(); q .pop(); for (int v : tree [u]) { if (!visited [v]) { visited [v] = true ; dist [v] = dist [u] + 1; q .push(v); } } } }
哈夫曼编码的生成过程基于贪心算法,出现频率越高的字符,其编码长度一定不会比出现频率更低的字符更长。
在 n 位格雷码中,任意两个编码之间都只相差一个二进制位。
下列一维动态规划代码实现的是完全背包问题,因为在处理第i 种物品时,同一种物品可能被重复选择。
for (int i = 0 ; i < n ; ++i) { for (int w = weight [i]; w <= W; ++w) { dp [w] = max (dp [w], dp [w - weight [i]] + value [i]); } }
下列递归程序能得到正确的斐波那契数,其时间复杂度和空间复杂度都是O(n)。
int fib(int n) { if (n <= 1) return n ; return fib(n - 1) + fib(n - 2); }
给定 n 个整数构成的数组 A=[a1,a2,...,an]。
你需要将数组 A 划分为若干非空连续子段。对于划分得到的某个子段,它的偏差值定义为子段内整数和的平方。划
分方案的偏差值定义为所有子段偏差值之和。
你需要最小化划分方案的偏差值。
形式化地,你可以将 A 划分为若干非空连续子段A1,A2,...,Ak,使得A=A1十A2十...Ak,这里的 + 代表数组的连接。对于 1≤i≤k,设数组包含 mi 个整数。你需要最小化 。
第一行,一个正整数n,表示数组A的长度。
第二行,n个整数a1,a2,....an,表示数组A。
一行,一个整数,表示划分方案偏差值的最小值。
1≤n≤2000,-100 ≤ai≤100
4
1 2 -3 4
6
-1 -1 4 -5 -1 4
0
老师有一棵有 n 个结点的树,结点依次以 1,2,...,n 编号。
老师想将这棵树作为奖品分给两位同学。具体而言,老师会选择一条边并从树上删去它,从而将这棵树分为两个连
通块。两位同学分别可以得到其中一个连通块。
如果有同学拿到的连通块结点数明显小于另一位同学,那么这位同学会不太高兴。为了避免这种情况出现,老师想
知道两个连通块结点数之差的绝对值最小是多少。
第一行,一个正整数n,表示结点数量。
接下来 n-1 行,每行两个正整数ui,vi,表示一条连接结点ui和结点vi的边。
输出一行,一个整数,表示答案。
2≤n≤2×10^4
1 2
2 3
3 4
1 3
1 4
1 5
5 6
2