信奥刷题站
CSP-S 初赛2024-09

2024年 CSP-S 第一轮(提高级)

题量
42 题
客观题
42 题
建议时长
120 分钟
卷面总分
100 分
开始整卷模拟计时作答 · 交卷即时判分 · 错题自动进错题本(需登录)

// questions

题目预览

单项选择题
1
单选题2

在 Linux 系统中,如果你想显示当前工作目录的路径,应该使用哪个命令?

A

pwd

B

cd

C

ls

D

echo

2
单选题2

假设一个长度为n的整数数组中每个元素值互不相同,且这个数组是无序的。要找到这个数组中最大元素的时间复杂度是多少?()

A

O(n)\mathcal{O}(n)O(n)

B

O(log⁡n)\mathcal{O}(\log{n})O(logn)

C

O(nlog⁡n)\mathcal{O}(n\log{n})O(nlogn)

D

O(1)\mathcal{O}(1)O(1)

3
单选题2

在c++中,以下哪个函数调用会造成栈溢出?()

A

int foo() { return 0; }

B

int bar() { int x = 1; return x; }

C

void baz() { int a[1000]; baz(); }

D

void qux() { return; }

4
单选题2

在一场比赛中,有 101010 名选手参加,前三名将获得金、银、铜牌。若不允许并列,且选手只能获得一枚奖牌,则不同的颁奖方式共有多少种?()

A

120120120

B

720720720

C

504504504

D

100010001000

5
单选题2

下面哪个数据结构最适合实现先进先出(FIFO)的功能?()

A

B

队列

C

线性表

D

二叉搜索树

6
单选题2

已知 f(1)=1f(1)=1f(1)=1,且对于 n≥2n \geq 2n2f(n)=f(n−1)+f(⌊n2⌋)f(n)=f(n-1)+f(\lfloor{\frac{n}{2}}\rfloor)f(n)=f(n1)+f(⌊2n⌋),则 f(4)f(4)f(4) 的值为:( )

A

444

B

555

C

666

D

777

7
单选题2

假设有一个包含 nnn 个顶点的无向图,且该图是欧拉图。以下关于该图的描述中哪一项不一定正确?()

A

所有顶点的度数均为偶数

B

该图连通

C

该图存在一个欧拉回路

D

该图的边数是奇数

8
单选题2

对数组进行二分查找的过程中,以下哪个条件必须满足?( )

A

数组必须是有序的

B

数组必须是无序的

C

数组长度必须是 222 的幂

D

数组中的元素必须是整数

9
单选题2

考虑一个自然数 nnn 以及一个模数 mmm,你需要计算 nnn 的逆元(即 nnn 在模 mmm 意义下的乘法逆元)。 下列哪种算法最为适合?( )

A

使用暴力法依次尝试

B

使用扩展欧几里得算法

C

使用快速幂法

D

使用线性筛法

10
单选题2

在设计一个哈希表时,为了减少冲突,需要使用适当的哈希函数和冲突解决策略。已知某哈希表中有 nnn 个键值对,表的装载因子为 a(0<a≤1)a(0 < a \leq 1)a(0<a1)。在使用开放地址法解决冲突的过程中,最坏情况下查找一个元素的时间复杂度为( )

A

O(1)\mathcal{O}(1)O(1)

B

O(log⁡n)\mathcal{O}(\log{n})O(logn)

C

O(11−a)\mathcal{O}(\frac{1}{1-a})O(1a1)

D

O(n)\mathcal{O}(n)O(n)

11
单选题2

假设有一棵 hhh 层的完全二叉树,该树最多包含多少个结点?

A

2h−12^h-12h1

B

2h+1−12^{h+1}-12h+11

C

2h2^h2h

D

2h+12^{h+1}2h+1

12
单选题2

设有一个 101010 个顶点的完全图,每两个顶点之间都有一条边。有多少个长度为 444 的环?()

A

120120120

B

210210210

C

630630630

D

504050405040

13
单选题2

对于一个整数 nnn,定义 f(n)f(n)f(n)nnn 的各位数字之和。问使 f(f(x))=10f(f(x))=10f(f(x))=10 的最小自然数 xxx 是多少?( )

A

292929

B

199199199

C

299299299

D

399399399

14
单选题2

设有一个长度为 nnn01 字符串,其中有 kkk1,每次操作可以交换相邻两个字符。在最坏情况下将这 kkk1移到字符串最右边所需要的交换次数是多少?( )

A

kkk

B

k×k−12k\times \frac{k-1}{2}k×2k1

C

(n−k)×k(n-k)\times k(nk)×k

D

(2n−k−1)×k2(2n-k-1)\times \frac{k}{2}(2nk1)×2k

15
单选题2

如图是一张包含 777 个顶点的有向图。如果要删除其中一些边,使得节点 1 到节点 7 没有可行路径,且删除的边数最少,请问有多少种可行的删除边的集合?

[图片]

A

111

B

222

C

333

D

444

阅读程序
16
判断题1
阅读程序代码(共 16-20 题共用)
#include <iostream>
using namespace std;

const int N = 1000;
int c[N];

int logic(int x, int y) {
    return (x & y) ^ ((x ^ y) | (~x & y));
}
void generate(int a, int b, int *c) {
    for (int i = 0; i < b; i++) {
        c[i] = logic(a, i) % (b + 1);
    }
}
void recursion(int depth, int *arr, int size) {
    if (depth <= 0 || size <= 1) return;
    int pivot = arr[0];
    int i = 0, j = size - 1;
    while (i <= j) {
        while (arr[i] < pivot) i++;
        while (arr[j] > pivot) j--;
        if (i <= j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    recursion(depth - 1, arr, j + 1);
    recursion(depth - 1, arr + i, size - i);
}

int main() {
    int a, b, d;
    cin >> a >> b >> d;
    generate(a, b, c);
    recursion(d, c, b);
    for (int i = 0; i < b; ++i) cout << c[i] << " ";
    cout << endl;
}

1000≥d≥b1000\geq d\geq b1000db 时,输出的序列是有序的。()

A

正确

B

错误

17
判断题1

当输入 5 5 1 时,输出为 1 1 5 5 5。()

A

正确

B

错误

18
判断题1

假设数组 c 长度无限制,该程序所实现的算法的时间复杂度是 O(b)\mathcal{O}(b)O(b) 的。

A

正确

B

错误

19
单选题3

函数 int logic(int x, int y) 的功能是()

A

按位与

B

按位或

C

按位异或

D

以上都不是

20
单选题4

当输入为 10 100 100 时,输出的第 100100100 个数是( )

A

919191

B

949494

C

959595

D

989898

21
判断题1
阅读程序代码(共 21-26 题共用)
#include <iostream>
#include <string>
using namespace std;

const int P = 998244353, N = 1e4 + 10, M = 20;
int n, m;
string s;
int dp[1<<M];

int solve() {
    dp[0] = 1;
    for (int i = 0; i < n; ++i) {
        for (int j = (1<<(m-1))-1; j >= 0; --j) {
            int k = (j<<1)|(s[i]-'0');
            if (j != 0 || s[i] == '1') {
                dp[k] = (dp[k] + dp[j]) % P;
            }
        }
    }
    int ans = 0;
    for (int i = 0; i < (1<<m); ++i) {
        ans = (ans + 1LL * i * dp[i]) % P;
    }
    return ans;
}
int solve2() {
    int ans = 0;
    for (int i = 0; i < (1<<n); ++i) {
        int cnt = 0;
        int num = 0;
        for (int j = 0; j < n; ++j) {
            if (i & (1<<j)) {
                num = num * 2 + (s[j]-'0');
                cnt++;
            }
        }
        if (cnt <= m) (ans += num) %= P;
    }
    return ans;
}

int main() {
    cin >> n >> m;
    cin >> s;
    if (n <= 20) {
        cout << solve2() << endl;
    }
    cout << solve() << endl;
    return 0;
}

假设数组 dp 长度无限制,函数 solve() 所实现的算法的时间复杂度是 O(n×2m)\mathcal{O}(n\times 2^m)O(n×2m)。()

A

正确

B

错误

22
判断题1

输入 11 2 10000000001 吋,程序输出两个数 3223。( )

A

正确

B

错误

23
判断题2

n≤10n\leq 10n10 时,solve() 的返回值始终小于 4104^{10}410( )

A

正确

B

错误

24
单选题3

n=10n=10n=10m=10m= 10m=10 时,有多少种输入使得两行的结果完全一致?

A

102410241024

B

111111

C

101010

D

000

25
单选题3

n≤6n \leq 6n6 时, solve() 的最大可能返回值为( )

A

656565

B

211211211

C

665665665

D

205920592059

26
单选题3

n=8n=8n=8m=8m=8m=8solvesolve2 的返回值的最大可能的差值为()

A

147714771477

B

199519951995

C

205920592059

D

218721872187

27
判断题1
阅读程序代码(共 27-32 题共用)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1000005;
const int P1 = 998244353, P2 = 1000000007;
const int B1 = 2, B2 = 31;
const int K1 = 0, K2 = 13;

typedef long long ll;

int n;
bool p[maxn];
int p1[maxn], p2[maxn];

struct H {
    int h1, h2, l;
    H(bool b = false) {
        h1 = b + K1;
        h2 = b + K2;
        l = 1;
    }
    H operator + (const H &h) const {
        H hh;
        hh.l = l + h.l;
        hh.h1 = (ll * h1 * p1[h.l] + h.h1) % P1;
        hh.h2 = (ll * h2 * p2[h.l] + h.h2) % P2;
        return hh;
    }
    bool operator == (const H &h) const {
        return l == h.l && h1 == h.h1 && h2 == h.h2;
    }
    bool operator < (const H &h) const {
        if (l != h.l) return l < h.l;
        else if (h1 != h.h1) return h1 < h.h1;
        else return h2 < h.h2;
    }
} h[maxn];

void init() {
    memset(p, 1, sizeof(p));
    p[0] = p[1] = false;
    p1[0] = p2[0] = 1;
    for (int i = 1; i <= n; ++i) {
        p1[i] = (ll * B1 * p1[i - 1]) % P1;
        p2[i] = (ll * B2 * p2[i - 1]) % P2;
        if (!p[i]) continue;
        for (int j = 2 * i; j <= n; j += i) {
            p[j] = false;
        }
    }
}
int solve() {
    for (int i = n; i; --i) {
        h[i] = H(p[i]);
        if (2 * i + 1 <= n) {
            h[i] = h[2 * i] + h[i] + h[2 * i + 1];
        } else if (2 * i <= n) {
            h[i] = h[2 * i] + h[i];
        }
    }
    cout << h[1].h1 << endl;
    sort(h + 1, h + n + 1);
    int m = unique(h + 1, h + n + 1) - (h + 1);
    return m;
}

int main() {
    cin >> n;
    init();
    cout << solve() << endl;
}

假设程序运行前能自动将 maxn 改为 n + 1,所实现的算法的时间复杂度是 O(nlog⁡n)\mathcal{O}(n\log{n})O(nlogn)

A

正确

B

错误

28
判断题1

时间开销的瓶颈是 init() 函数。

A

正确

B

错误

29
判断题1

若修改常数 B1K1 的值,该程序可能会输出不同的结果。

A

正确

B

错误

30
单选题3

solve() 函数中,h[] 的合并顺序可以看作是:

A

二叉树的BFS序

B

二叉树的先序遍历

C

二叉树的中序遍历

D

二叉树的后序遍历

31
单选题3

输入 10,输出的第一行是?

A

838383

B

424424424

C

545454

D

110101000110101000110101000

32
单选题4

(4分)输入 16,输出的第二行是?

A

777

B

999

C

101010

D

121212

完善程序
33
单选题3
阅读程序代码(共 33-37 题共用)
#include <iostream>
using namespace std;

const int maxn = 100005;

int n;
long long k;
int a[maxn], b[maxn];

int* upper_bound(int *a, int *an, int ai) {
    int l = 0, r = ①;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (②) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    return ③;
}

long long get_rank(int sum) {
    long long rank = 0;
    for (int i = 0; i < n; ++i) {
        rank += upper_bound(b, b + n, sum - a[i]) - b;
    }
    return rank;
}

int solve() {
    int l = 0, r = ④;
    while (l < r) {
        int mid = ((long long)l + r) >> 1;
        if (⑤) {
            l = mid + 1;
        } else {
            r = mid;
        }
    }
    return l;
}

int main() {
    cin >> n >> k;
    for (int i = 0; i < n; ++i) cin >> a[i];
    for (int i = 0; i < n; ++i) cin >> b[i];
    cout << solve() << endl;
}

① 处应填

A

an - a

B

an - a - 1

C

ai

D

ai + 1

34
单选题3

② 处应填

A

a[mid] > ai

B

a[mid] >= ai

C

a[mid] < ai

D

a[mid] <= ai

35
单选题3

③ 处应填

A

a + l

B

a + l + 1

C

a + l - 1

D

an - l

36
单选题3

④ 处应填

A

a[n - 1] + b[n - 1]

B

a[n] + b[n]

C

2 * maxn

D

maxn

37
单选题3

⑤ 处应填

A

get_rank(mid) < k

B

get_rank(mid) <= k

C

get_rank(mid) > k

D

get_rank(mid) >= k

38
单选题3
阅读程序代码(共 38-42 题共用)
#include <cstdio>
#include <queue>
#include <utility>
#include <cstring>
using namespace std;

const int maxn = 2e5+10, maxm = 1e6+10, inf = 522133279;

int n, m, s, t;
int head[maxn], nxt[maxm], to[maxm], w[maxm], tot = 1;
int dis[maxn<<1], *dis2;
int pre[maxn<<1], *pre2;
bool vis[maxn<<1];

void add(int a, int b, int c) {
    ++tot;
    nxt[tot] = head[a];
    head[a] = tot;
    to[tot] = b;
    w[tot] = c;
}

bool upd(int a, int b, int d, priority_queue<pair<int, int>> &q) {
    if (d >= dis[b]) return false;
    if (b < n) ①;
    q.push(②);
    dis[b] = d;
    pre[b] = a;
    return true;
}

void solve() {
    priority_queue<pair<int, int>> q;
    q.push(make_pair(0, s));
    memset(dis, ③, sizeof(dis));
    memset(pre, -1, sizeof(pre));
    dis2 = dis + n;
    pre2 = pre + n;
    dis[s] = 0;
    while (!q.empty()) {
        int a = q.top().second; q.pop();
        if (vis[a]) continue;
        vis[a] = true;
        int aa = a % n;
        for (int e = head[aa]; e; e = nxt[e]) {
            int b = to[e], c = w[e];
            if (a < n) {
                if (!upd(a, b, dis[a] + c, q)) ④;
            } else {
                upd(a, n + b, dis2[a] + c, q);
            }
        }
    }
}

void out(int a) {
    if (a != s) {
        if (a < n) out(pre[a]);
        else out(⑤);
    }
    printf("%d%c", a%n+1, " \n"[a == n + t]);
}

int main() {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    --s, --t;
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a - 1, b - 1, c);
    }
    solve();
    if (dis2[t] == inf) puts("-1");
    else {
        printf("%d\n", dis2[t]);
        out(n + t);
    }
}

① 处应填

A

upd(pre[b], n + b, dis[b], q)

B

upd(a, n + b, d, q)

C

upd(pre[b], b, dis[b], q)

D

upd(a, b, d, q)

39
单选题3

② 处应填

A

make_pair(-d, b)

B

make_pair(d, b)

C

make_pair(b, d)

D

make_pair(-b, d)

40
单选题3

③ 处应填

A

0xff

B

0x1f

C

0x3f

D

0x7f

41
单选题3

④ 处应填

A

upd(a, n + b, dis[a] + c, q)

B

upd(n + a, n + b, dis2[a] + c, q)

C

upd(n + a, b, dis2[a] + c, q)

D

upd(a, b, dis[a] + c, q)

42
单选题3

⑤ 处应填

A

pre2[a]

B

pre2[a % n]

C

pre[a % n]

D

pre[a % n]+1