5620:[GESP202609五级] 客观题

文件提交:无需freopen 内存限制:128 MB 时间限制:1.000 S
评测方式:文本裁判
金币值:
命题人:
提交:0 解决:0

题目描述

## 一、单选题(每题 2 分,共 30 分) **第 1 题** 小杨用单链表保存任务序列,并同时维护头指针 `head` 和尾指针 `tail`。在链表非空且已知 `tail` 的情况下,在表尾插入新结点的时间复杂度是(  ) ```cpp 01 struct Node { 02 int value; 03 Node *next; 04 }; 05 06 Node *head; 07 Node *tail; ``` - $O(1)$ - $O(\log n)$ - $O(n)$ - $O(n\log n)$ **第 2 题** 在不带哨兵结点的双向链表中,结点 `p` 既不是头结点也不是尾结点。删除 `p` 的正确代码是(  ) ```cpp 01 struct Node { 02 int value; 03 Node *prev; 04 Node *next; 05 }; ``` - ```cpp 01 p->prev = p->next; 02 p->next = p->prev; 03 delete p; ``` - ```cpp 01 p->prev->next = p; 02 p->next->prev = p; 03 delete p; ``` - ```cpp 01 p->prev->next = p->next; 02 p->next->prev = p->prev; 03 delete p; ``` - ```cpp 01 p->next = p->prev; 02 p->prev->next = nullptr; 03 delete p; ``` **第 3 题** 下面函数使用快慢指针查找单链表的中间结点。横线处应填写(  ) ```cpp 01 struct Node { 02    int value; 03    Node *next; 04 }; 05 06 Node *middle(Node *head) { 07    Node *slow = head; 08    Node *fast = head; 09    while (fast != nullptr && fast->next != nullptr) { 10        slow = slow->next; 11        ______________________ 12   } 13    return slow; 14 } ``` - `fast = fast->next;` - `fast = fast->next->next;` - `fast = slow->next;` - `fast = head->next;` **第 4 题** 函数 `gcd(int a, int b)` 定义如下,则 `gcd(105, 45)` 的结果是(  ) ```cpp 01 int gcd(int a, int b) { 02    return b == 0 ? a : gcd(b, a % b); 03 } ``` - $3$ - $5$ - $15$ - $45$ **第 5 题** 下面函数用于判断正整数 $n$ 是否为质数。横线处的最佳写法是(  ) ```cpp 01 bool isPrime(int n) { 02    if (n < 2) 03        return false; 04    for (int i = 2; __________________; i++) { 05        if (n % i == 0) 06            return false; 07   } 08    return true; 09 } ``` - `i < n` - `i <= n / 2` - `i * i < n` - `(long long) i * i <= n` **第 6 题** 下面代码实现线性筛法。为了保证每个合数只被其最小质因子筛去一次,横线处应填写(  ) ```cpp 01 vector linearSieve(int n) { 02    vector composite(n + 1, false); 03    vector primes; 04 05 for (int i = 2; i <= n; i++) { 06        if (!composite[i]) 07            primes.push_back(i); 08        for (int p : primes) { 09            if ((long long)i * p > n) 10                break; 11            composite[i * p] = true; 12            if (__________________) 13                break; 14       } 15   } 16    return primes; 17 } ``` - `p % i == 0` - `i % p == 0` - `i == p` - `i * p == n` **第 7 题** 根据唯一分解定理,整数 $756$ 的正确质因数分解是(  ) - $2^2 \times 3^3 \times 7$ - $2^3 \times 3^2 \times 7$ - $2^2 \times 3^2 \times 21$ - $2 \times 3^3 \times 14$ **第 8 题** 函数 `f(int n)` 定义如下,则 `f(4)` 的结果是(  ) ```cpp 01 int f(int n) { 02    if (n == 1) 03        return 1; 04    return n + f(n - 1); 05 } ``` - $4$ - $7$ - $9$ - $10$ **第 9 题** 在升序数组中查找第一个严格大于 `x` 的元素位置,下面代码中的横线应填写(  ) ```cpp 01 int upperBound(const vector &a, int x) { 02    int l = 0, r = (int)a.size(); 03    while (l < r) { 04        int mid = l + (r - l) / 2; 05        if (__________________) { 06            l = mid + 1; 07       } else { 08            r = mid; 09       } 10   } 11    return l; 12 } ``` - `a[mid] < x` - `a[mid] >= x` - `a[mid] <= x` - `a[mid] > x` **第 10 题** 小杨需要把若干箱货物按原顺序分配到 `days` 天中,每天运输连续的若干箱,求能够完成任务的最小载重量。函数 `check(cap)` 判断载重量为 `cap` 时能否在规定天数内运完。横线处应填写(  ) ```cpp 01 long long l = maxWeight; 02 long long r = totalWeight; 03 04 while (l < r) { 05    long long mid = l + (r - l) / 2; 06    if (check(mid)) { 07        ____________________ 08   } else { 09        ____________________ 10   } 11 } 12 cout << l; ``` - `l = mid + 1; 和 r = mid;` - `r = mid; 和 l = mid + 1;` - `r = mid - 1; 和 l = mid;` - `l = mid; 和 r = mid - 1;` **第 11 题** 下面是归并排序中合并两个有序区间(升序排序)的部分代码。若希望排序保持稳定,横线处应填写(  ) ```cpp 01 while (i <= mid && j <= right) { 02    if (__________________) { 03        temp.push_back(a[i++]); 04   } else { 05        temp.push_back(a[j++]); 06   } 07 } ``` - `a[i] < a[j]` - `a[i] > a[j]` - `a[i] >= a[j]` - `a[i] <= a[j]` **第 12 题** 下面快速排序的划分函数以 `a[right]` 为枢轴,并把不大于枢轴的元素移动到左侧。横线处应填写(  ) ```cpp 01 int partition(int a[], int left, int right) { 02    int pivot = a[right]; 03    int i = left - 1; 04    for (int j = left; j < right; j++) { 05        if (__________________) { 06            i++; 07            swap(a[i], a[j]); 08       } 09   } 10    swap(a[i + 1], a[right]); 11    return i + 1; 12 } ``` - `a[j] <= pivot` - `a[j] > pivot` - `a[i] <= pivot` - `a[right] < a[j]` **第 13 题** 小杨要在一个教室安排尽可能多场活动,每场活动具有开始时间 `start` 和结束时间 `end`。采用贪心算法时,正确的选择策略是(  ) ```cpp 01 struct Activity { 02    int start; 03    int end; 04 }; ``` - 每次选择开始时间最早的活动 - 每次选择持续时间最短的活动 - 每次选择参与人数最少的活动 - 按结束时间从早到晚排序,依次选择与已选活动不冲突的活动 **第 14 题** 下面函数使用迭代方法求最大连续子段和。对于数组 `{-2, 3, -1, 5, -6, 2}`,函数返回值是(  ) ```cpp 01 int maxSubArray(const vector &a) { 02    int best = a[0]; 03    int current = a[0]; 04    for (int i = 1; i < (int)a.size(); i++) { 05        current = max(a[i], current + a[i]); 06        best = max(best, current); 07   } 08    return best; 09 } ``` - $5$ - $6$ - $7$ - $8$ **第 15 题** 数组 $a$ 和 $b$ 按低位在前的顺序保存两个非负大整数。下面代码实现高精度加法,横线处应填写(  )。 ```cpp 01 vector add(const vector &a, const vector &b) { 02    vector c; 03    int carry = 0; 04    int n = max(a.size(), b.size()); 05 06 for (int i = 0; i < n; i++) { 07        int sum = carry; 08        if (i < a.size()) 09            sum += a[i]; 10        if (i < b.size()) 11            sum += b[i]; 12        c.push_back(sum % 10); 13        ____________________ 14   } 15    if (carry) 16        c.push_back(carry); 17    return c; 18 } ``` - `carry = sum % 10;` - `carry = sum;` - `carry = sum / 10;` - `carry = c[i] / 10;` ## 二、判断题(每题 2 分,共 20 分) **第 1 题** 下面代码在已知结点 $p$ 的情况下,能够以 $O(1)$ 的时间在单链表的 $p$ 结点之后插入新结点 $s$。 ```cpp 01 s->next = p->next; 02 p->next = s; ``` - 正确 - 错误 **第 2 题** 下面代码可以安全地删除单链表的头结点,并使 `head` 指向删除后的新头结点。 ```cpp 01 Node *p = head; 02 delete p; 03 head = p->next; ``` - 正确 - 错误 **第 3 题** 下面欧几里得算法既适用于 `a > b`,也适用于 `a < b`,只要 `a`、`b` 是正整数。 ```cpp 01 int gcd(int a, int b) { 02    while (b != 0) { 03        int r = a % b; 04        a = b; 05        b = r; 06   } 07    return a; 08 } ``` - 正确 - 错误 **第 4 题** 下面埃氏筛从 `i * i` 开始标记,是因为 `i * i` 之前的 `i` 的合数倍数已经被更小的质因子标记过。 ```cpp 01 for (int i = 2; (long long)i * i <= n; i++) { 02    if (isPrime[i]) { 03        for (int j = i * i; j <= n; j += i) { 04            isPrime[j] = false; 05       } 06   } 07 } ``` - 正确 - 错误 **第 5 题** 下面程序的时间复杂度为 $O(n)$。 ```cpp 01 for (int i = 1; i <= n; i *= 2) { 02    cout << i << endl; 03 } ``` - 正确 - 错误 **第 6 题** 若数组 $a$ 已按升序排列,下面函数能够返回最后一个小于等于 $x$ 的元素下标;如果不存在,则返回 $-1$。 ```cpp 01 int findLastLE(const vector &a, int x) { 02    int l = 0, r = (int)a.size() - 1; 03    int ans = -1; 04    while (l <= r) { 05        int mid = l + (r - l) / 2; 06        if (a[mid] <= x) { 07            ans = mid; 08            l = mid + 1; 09       } else { 10            r = mid - 1; 11       } 12   } 13    return ans; 14 } ``` - 正确 - 错误 **第 7 题** 快速排序中如果选取区间第一个元素作为枢轴。当输入数组已经升序排列时,其最坏时间复杂度仍为 $O(n\log n)$。 - 正确 - 错误 **第 8 题** 归并排序的递推式为 $T(n) = 2T(n/2) + O(n)$,对应的时间复杂度为 $O(n\log n)$。 - 正确 - 错误 **第 9 题** 下面的贪心代码一定能对任意硬币面值集合 `coins` 求出 `money` 所需的最少硬币数。 ```cpp 01 int count = 0; 02 for (int coin : coins) { // coins 按面值从大到小排列 03    count += money / coin; 04    money %= coin; 05 } ``` - 正确 - 错误 **第 10 题** 假设两个非负高精度整数分别存储在数组 `a` 和 `b` 中,且 $a \ge b$。数组采用低位在前的方式存储,即 `a[0]` 表示个位。下面代码中的 `c` 可以正确保存 $a - b$ 的各位数字。 ```cpp 01 int borrow = 0; 02 for (int i = 0; i < len; ++i) { 03    int t = a[i] - b[i] + borrow; 04    if (t < 0) { 05        t += 10; 06        borrow = 1; 07   } else { 08        borrow = 0; 09   } 10    c[i] = t; 11 } ``` - 正确 - 错误

来源/分类