近年来,线上授课变得普遍,很多有助于改善教学效果的设备也逐渐流行,其中包括比较常用的手写板,那么它属于哪类设备?( )。
A:输入设备。手写板将书写笔迹实时转换为数字信号送入计算机,用于输入文字与绘图,与鼠标键盘同类,属于输入设备,而非输出、控制或记录设备。
如果 a 和 b 均为 int 类型的变量,且 b 的值不为 ,那么下列能正确判断"a 是 b 的 倍"的表达式是( )。
D:a == 3 * b。A 中 >>3 是除以 8 而非 3 倍;B 只保证 a-b 是 3 的倍数,如 5 与 2 差为 3 却非 3 倍;C 中整数除法 7/2=3 会把 7 误判为 2 的 3 倍。
如果变量 a 和 b 分别为 double 类型和 int 类型,则表达式 (a = 6, b = 3 * (7 + 8) / 2, b += a) 的计算结果为( )。
C:28。逗号表达式从左到右求值:a=6,b=3×(7+8)/2=45/2=22(int 除法舍去小数),再 b+=a 得 22+6=28,整个表达式取最后一项的值 28。
有关下面 C++ 代码说法错误的是( )。
01// sumA()和sumB()用于求从1到N之和 02#include <iostream> 03using namespace std; 04int sumA(int n) { 05 int sum = 0; 06 for (int i = 1; i < n + 1; i++) 07 sum += i; 08 return sum; 09} 10int sumB(int n) { 11 if (n == 1) 12 return 1; 13 else 14 return n + sumB(n - 1); 15} 16int main() { 17 int n = 0; 18 cin >> n; 19 cout << sumA(n) << " " << sumB(n) << endl; 20 return 0; 21}
C:输入 100000 时无法求和。sumA 循环 10 万次没问题,但 sumB 递归深度达 100000,远超默认栈容量必然栈溢出;1000 层递归通常可行,循环一般比递归高效。
下面 C++ 代码以递归方式实现字符串反序,横线处应填上代码是( )。
01//字符串反序 02#include <iostream> 03#include <string> 04using namespace std; 05string sReverse(string sIn) { 06 if (sIn.length() <= 1) { 07 return sIn; 08 } else { 09 return ____________ // 此处填写代码 10 } 11} 12int main() { 13 string sIn; 14 cin >> sIn; 15 cout << sReverse(sIn) << endl; 16 return 0; 17}
A:sIn[sIn.length()-1] + sReverse(sIn.substr(0, sIn.length()-1))。把末字符提到最前,再对去掉末字符的前缀递归反序,例如 abc 得 c 加反序 ab 得到 cba。
印度古老的汉诺塔传说:创世时有三根金刚柱,其中一柱从下往上按照大小顺序摞着 片黄金圆盘,当圆盘逐一从一柱借助另外一柱全部移动到另外一柱时,宇宙毁灭。移动规则:在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。下面的 C++ 代码以递归方式实现汉诺塔,横线处应填入代码是( )。
01#include <iostream> 02using namespace std; 03// 递归实现汉诺塔,将N个圆盘从A通过B移动C 04// 圆盘从底到顶,半径必须从大到小 05void Hanoi(string A, string B, string C, int N) { 06 if (N == 1) { 07 cout << A << " -> " << C << endl; 08 } else { 09 Hanoi(A, C, B, N - 1); 10 cout << A << " -> " << C << endl; 11 ____________; // 此处填写代码 12 } 13} 14int main() { 15 Hanoi("甲", "乙", "丙", 3); 16 return 0; 17}
B:Hanoi(B, A, C, N-1)。第一步把 N-1 个盘从 A 经 C 移到 B,输出 A→C 移最大盘后,须把 B 上 N-1 个盘经 A 移到 C,正是 Hanoi(B,A,C,N-1)。
根据下面 C++ 代码的注释,两个横线处应分别填入( )。
01#include <iostream> 02#include <vector> 03#include <algorithm> 04using namespace std; 05 06bool isOdd(int N) { 07 return N % 2 == 1; 08} 09bool compare(int a, int b) { 10 if (a % 2 == 0 && b % 2 == 1) 11 return true; 12 return false; 13} 14int main() { 15 vector<int> lstA; // lstA是一个整型向量 16 for (int i = 1; i < 100; i++) 17 lstA.push_back(i); 18 // 对lstA成员按比较函数执行结果排序 19 sort(lstA.begin(), lstA.end(), ____________); // 此处填写代码1 20 21 vector<int> lstB; 22 for (int i = 0; i < lstA.size(); i++) // lstB成员全为奇数 23 if (____________) // 此处填写代码2 24 lstB.push_back(lstA[i]); 25 26 cout << "lstA: "; 27 for (int i = 0; i < lstA.size(); i++) 28 cout << lstA[i] << " "; 29 cout << endl; 30 31 cout << "lstB: "; 32 for (int i = 0; i < lstB.size(); i++) 33 cout << lstB[i] << " "; 34 cout << endl; 35 return 0; 36}
A:compare 和 isOdd(lstA[i])。sort 第三参传函数名 compare(不带括号和参数);代码 2 在 for 循环内逐个判断当前元素,须写 isOdd(lstA[i]),传函数名无法判断具体元素。
有关下面代码正确的是( )。
01// 在C++语言中,可以通过函数指针的形式,将一个函数作为另一个函数的参数。 02// 具体来说:bool checkNum(bool (*Fx)(int), int N); 声明了一个函数, 03// 其第一个参数是函数指针类型,指向一个接收一个int参数且返回值为bool的函数。 04#include <iostream> 05using namespace std; 06 07bool isEven(int N) { 08 return N % 2 == 0; 09} 10bool checkNum(bool (*Fx)(int), int N) { 11 return Fx(N); 12} 13int main() { 14 cout << checkNum(isEven, 10) << endl; 15 return 0; 16}
C:输出 1。checkNum 的 Fx 指向 isEven,Fx(10) 即 10%2==0 返回 true,bool 值输出为 1;函数指针作参数的定义与调用均正确。
有关下面 C++ 代码正确的是( )。
01#include <iostream> 02using namespace std; 03 04bool isOdd(int N) { 05 return N % 2 == 1; 06} 07int Square(int N) { 08 return N * N; 09} 10bool checkNum(bool (*Fx)(int), int x) { 11 return Fx(x); 12} 13int main() { 14 cout << checkNum(isOdd, 10) << endl; // 输出行A 15 cout << checkNum(Square, 10) << endl; // 输出行B 16 return 0; 17}
C:输出行 B 编译错误。checkNum 的参数要求 bool(*)(int) 函数指针,isOdd 签名匹配可行;Square 返回 int 与签名不符,checkNum(Square, 10) 传参类型不匹配导致编译错误。
下面代码执行后的输出是( )。
01#include <iostream> 02using namespace std; 03 04int jumpFloor(int N) { 05 cout << N << "#"; 06 if (N == 1 || N == 2) { 07 return N; 08 } else { 09 return jumpFloor(N - 1) + jumpFloor(N - 2); 10 } 11} 12int main() { 13 cout << jumpFloor(4) << endl; 14 return 0; 15}
D:4#3#2#1#2#5。jumpFloor(4) 先输出 4#,再递归 jumpFloor(3) 输出 3#、其内 jumpFloor(2) 输出 2#、jumpFloor(1) 输出 1#,随后另一 jumpFloor(2) 输出 2#,返回值 2+1+2=5。
下面代码中的 isPrimeA() 和 isPrimeB() 都用于判断参数 N 是否素数,有关其时间复杂度的正确说法是( )。
01#include <iostream> 02#include <cmath> 03using namespace std; 04 05bool isPrimeA(int N) { 06 if (N < 2) 07 return false; 08 for (int i = 2; i < N; i++) 09 if (N % i == 0) 10 return false; 11 return true; 12} 13bool isPrimeB(int N) { 14 if (N < 2) 15 return false; 16 int endNum = int(sqrt(N)); 17 for (int i = 2; i <= endNum; i++) 18 if (N % i == 0) 19 return false; 20 return true; 21} 22int main() { 23 cout << boolalpha; 24 cout << isPrimeA(13) << " " << isPrimeB(13) << endl; 25 return 0; 26}
B:isPrimeA 最坏 O(N),isPrimeB 最坏 O(N^½)。isPrimeA 试除 2 到 N-1,isPrimeB 只试除到 sqrt(N),故 isPrimeB 优于 isPrimeA,二者对 13 均判为素数。
下面代码用于归并排序,其中 merge() 函数被调用次数为( )。
01#include <iostream> 02using namespace std; 03 04void mergeSort(int * listData, int start, int end); 05void merge(int * listData, int start, int middle, int end); 06 07void mergeSort(int * listData, int start, int end) { 08 if (start >= end) 09 return; 10 int middle = (start + end) / 2; 11 mergeSort(listData, start, middle); 12 mergeSort(listData, middle + 1, end); 13 merge(listData, start, middle, end); 14} 15void merge(int * listData, int start, int middle, int end) { 16 int leftSize = middle - start + 1; 17 int rightSize = end - middle; 18 19 int * left = new int[leftSize]; 20 int * right = new int[rightSize]; 21 for (int i = 0; i < leftSize; i++) 22 left[i] = listData[start + i]; 23 for (int j = 0; j < rightSize; j++) 24 right[j] = listData[middle + 1 + j]; 25 26 int i = 0, j = 0, k = start; 27 while (i < leftSize && j < rightSize) { 28 if (left[i] <= right[j]) { 29 listData[k] = left[i]; 30 i++; 31 } else { 32 listData[k] = right[j]; 33 j++; 34 } 35 k++; 36 } 37 38 while (i < leftSize) { 39 listData[k] = left[i]; 40 i++; 41 k++; 42 } 43 while (j < rightSize) { 44 listData[k] = right[j]; 45 j++; 46 k++; 47 } 48 delete[] left; 49 delete[] right; 50} 51int main() { 52 int lstA[] = {1, 3, 2, 7, 11, 5, 3}; 53 int size = sizeof(lstA) / sizeof(lstA[0]); 54 55 mergeSort(lstA, 0, size - 1); // 对lstA执行归并排序 56 57 for (int i = 0; i < size; i++) 58 cout << lstA[i] << " "; 59 cout << endl; 60 return 0; 61}
C:6。7 个元素归并时每次对长度≥2 的区间调用一次 merge,递归树有 n-1=6 个非叶子节点,merge 恰好被调用 6 次,与数据内容无关。
归并排序将序列不断分成两半、分别递归排序后再合并,这种算法设计思想属于( )。
B:分治算法。归并排序把序列不断二分、递归排序子序列,再合并两个有序序列,体现分解、解决、合并的分治三步,不是搜索、贪心或递推。
归并排序算法的基本思想是( )。
A:将数组分成两个子数组分别排序后再合并。B 是快速排序的枢轴划分,C、D 是冒泡排序的相邻比较交换,均不属于归并排序的基本思想。
有关下面代码的说法正确的是( )。
01#include <iostream> 02 03class Node { 04public: 05 int Value; 06 Node * Next; 07 08 Node(int Val, Node * Nxt = nullptr) { 09 Value = Val; 10 Next = Nxt; 11 } 12}; 13 14int main() { 15 Node * firstNode = new Node(10); 16 firstNode->Next = new Node(100); 17 firstNode->Next->Next = new Node(111, firstNode); 18 return 0; 19}
C:循环链表。第三节点用 new Node(111, firstNode) 把 Next 指向 firstNode,尾节点指回头节点,首尾相接成环;每节点只有一个 Next 指针,故非双向链表。
TCP/IP 的传输层的两个不同的协议分别是 UDP 和 TCP。
对。TCP/IP 模型的传输层正是 TCP 与 UDP 两个协议:TCP 面向连接、可靠传输,UDP 无连接、不保证可靠,二者并列构成传输层,说法正确。
在特殊情况下流程图中可以出现三角框和圆形框。
错。流程图图形符号有统一规定:起止用圆角矩形、判断用菱形、处理用矩形、输入输出用平行四边形,不存在三角框或圆形框,特殊情况也不能使用。
找出自然数 以内的所有质数,常用算法有埃氏筛法和线性筛法,其中埃氏筛法效率更高。
错。埃氏筛每个合数可能被多个质因子重复标记,复杂度 O(nloglogn);线性筛每个合数只被最小质因子筛一次,复杂度 O(n),线性筛效率更高。
在 C++ 中,可以使用二分法查找链表中的元素。
错。二分查找需要按下标 O(1) 取中位元素再决定区间,链表只能从头指针顺序遍历,无法随机访问,即使链表有序也不能用二分查找。
在 C++ 中,通过恰当的实现,可以将链表首尾相接,形成循环链表。
对。构造时把尾节点的 Next 指针指向头节点即可首尾相接形成循环链表,从任一节点出发都能绕环遍历回到自身,无需额外数据结构。
贪心算法的解可能不是最优解。
对。贪心每步只取当前看来最优的选择,不回头调整,如找零钱、背包等场景可能得不到全局最优解,只有满足贪心选择性质才保证最优。
一般说来,冒泡排序算法优于归并排序。
错。冒泡排序平均与最坏均为 O(n²),归并排序稳定且为 O(nlogn),数据量大时归并远优于冒泡,不能说冒泡一般优于归并。
C++ 语言中的 qsort 库函数是不稳定排序。
对。C 标准库 qsort 通常用快速排序实现,划分时枢轴与元素交换会打乱相等元素的相对顺序,属于不稳定排序,与归并排序的稳定不同。
质数的判定和筛法的目的并不相同,质数判定旨在判断特定的正整数是否为质数,而质数筛法意在筛选出范围内的所有质数。
对。质数判定只回答单个 N 是否为质数,试除到 sqrt(N) 即可;质数筛法(如埃氏筛)一次性筛出区间内全部质数,二者目的与输出规模都不同。
下面的 C++ 代码执行后将输出 0 5 1 6 2 3 4 。
01#include <iostream> 02#include <algorithm> 03using namespace std; 04 05bool compareModulo5(int a, int b) { 06 return a % 5 < b % 5; 07} 08int main() { 09 int lst[7]; 10 for (int i = 0; i < 7; i++) 11 lst[i] = i; 12 13 // 对序列所有元素按compareModulo5结果排序 14 sort(lst, lst + 7, compareModulo5); 15 16 for (int i = 0; i < 7; i++) 17 cout << lst[i] << " "; 18 cout << endl; 19 return 0; 20}
对。0~6 对 5 取模依次得 0,1,2,3,4,0,1,按余数升序分组:余 0 的 0、5,余 1 的 1、6,再是 2、3、4,正好输出 0 5 1 6 2 3 4。