2025年CSP-J同步赛
IOI

报名时间:2025-09-20 00:00 至 2025-09-21 23:59

竞赛时间:2025-09-20 10:15 至 2025-09-21 23:59 (时长:1天13小时44分

主办方:ACGO

已报名942

  • 得分

    --

  • 正确率

    --

只看错题

[单选题]

1.

下列表示数据的选项中,( )表示的数据最大。

  • A.

    36000KB

  • B.

    33MB

  • C.

    0.03GB

  • D.

    36500000B

  • 我的答案:

    --

  • 正确答案:

    A

  • 答案解析:

    【答案】AA
    【解析】不妨将单位全都转成 MBMB

    36000KB35.2MB36000 KB \approx 35.2 MB

    33MB=33MB33 MB = 33 MB

    0.03GB=30.72MB0.03 GB = 30.72 MB

    36500000B34.8MB36500000 B \approx 34.8 MB

    所以 36000KB36000 KB 最大。

2.

一棵二叉树中序遍历 DGBAECHF,后序遍历 GDBEHFCA,则前序遍历( )。

  • A.

    ABCDFGHE

  • B.

    ABDGCEFH

  • C.

    ACBGDHEF

  • D.

    ACEFHBGD

  • 我的答案:

    --

  • 正确答案:

    B

  • 答案解析:

    --

3.

一个人站在坐标 (0, 0) 处,面朝 x 轴正方向。第一轮,他向前走 1 单位距离,然后右转;第二轮,他向前走 2 单位距离,然后右转;第三轮,他向前走 3 单位距离,然后右转… 他一直这么走下去。则第 2023 轮后,他的坐标是( )。

  • A.

    (−1012, −1012)

  • B.

    (−1012, 1012)

  • C.

    (2022, 1012)

  • D.

    (2022, −1012)

  • 我的答案:

    --

  • 正确答案:

    A

  • 答案解析:

    --

4.

8 张椅子放成一排,4 人就座,其中恰有连续三个空位的做法有( )种。

  • A.

    360

  • B.

    480

  • C.

    720

  • D.

    1220

  • 我的答案:

    --

  • 正确答案:

    B

  • 答案解析:

    --

5.

( )算法的平均时间复杂度为 O(nlogn),其中 n 是待排序的元素个数。

  • A.

    冒泡排序

  • B.

    选择排序

  • C.

    快速排序

  • D.

    插入排序

  • 我的答案:

    --

  • 正确答案:

    C

  • 答案解析:

    快速排序算法的平均时间复杂度为 O(nlogn)O(nlogn)。其余皆是 O(n2)O(n^2).

6.

原字符串中任意一段连续的字符所组成的新字符串称为子串。则字符串 ABBCCC 共有( )个不同的非空子串。

  • A.

    11

  • B.

    14

  • C.

    17

  • D.

    20

  • 我的答案:

    --

  • 正确答案:

    C

  • 答案解析:

    • 以 A 开头共有 6 个不同的子串,分别是 A、AB、ABB、ABBC、ABBCC、ABBCCC ;
    • 以 B 开头共有 8 个不同的子串,分别是 B、BB、BBC、BBCC、BBCCC、BC、BCC、BCCC ;
    • 以 C 开头共有 3 个不同的子串,分别是 C、CC、CCC 。

    所以共有 6 + 8 + 3 = 14 个不同的非空子串.

7.

现有两张分辨率为2048×2048像素的128位真彩色图像。要存储这两张图像,需要多大的存储空间?( )。

  • A.

    32MB

  • B.

    64MB

  • C.

    128MB

  • D.

    256MB

  • 我的答案:

    --

  • 正确答案:

    C

  • 答案解析:

    --

8.

周末徐老师和爸爸妈妈三个人一起想动手做三道菜。徐老师负责洗菜、爸爸负责切菜、妈妈负责炒菜。假设做每道菜的顺序都是:先洗菜15分钟,然后切菜10分钟,最后炒菜20分钟。那么做一道菜需要45分钟。注意:两道不同的菜的相同步骤不可以同时进行。例如第一道菜和第二道的菜不能同时洗,也不能同时切。那么做完三道菜的最短时间需要( )分钟。

  • A.

    85

  • B.

    90

  • C.

    120

  • D.

    135

  • 我的答案:

    --

  • 正确答案:

    A

  • 答案解析:

    --

9.

表达式 (a+b)*(c+d)+e 的后缀形式是( )。

  • A.

    a+bc+d*+e

  • B.

    abcd++*+e

  • C.

    ab+cd+*e+

  • D.

    ab+cd+e+*

  • 我的答案:

    --

  • 正确答案:

    C

  • 答案解析:

    --

10.

设哈希表的地址空间为0到10,散列函数为hash(n)=n mod 11,用线性探查法解决碰撞。现从空的哈希表开始,依次插入关键码值84,25,38,57,71,则最后一个关键码71的地址为( )。

  • A.

    7

  • B.

    6

  • C.

    5

  • D.

    4

  • 我的答案:

    --

  • 正确答案:

    B

  • 答案解析:

    --

11.

3名医生和6名护士被分配到3所学校为学生体检,每校分配1名医生和2名护士,不同的分配方法共有( )种。

  • A.

    360

  • B.

    540

  • C.

    720

  • D.

    960

  • 我的答案:

    --

  • 正确答案:

    B

  • 答案解析:

    --

12.
  1. 设栈 S 和队列 Q 初始状态为空,元素 a1, a2, ..., a6 依次通过栈 S,一个元素出栈后就进入队列Q,若出队的顺序分别是 a2,a1,a3,a6, a5,a4则栈 S 的容量至少是( )
  • A.

    2

  • B.

    5

  • C.

    3

  • D.

    4

  • 我的答案:

    --

  • 正确答案:

    C

  • 答案解析:

    【答案】C
    【解析】:模拟栈的行为,可以发现最后需要保持 a4, a5, a6 同时处于栈中。

13.
  1. 逻辑表达式( )的值与变量 A 的真假无关。
  • A.

    (A ∧ B) ∨ (¬A ∧ B)

  • B.

    (A ∨ B) ∧ ¬A

  • C.

    (A ∨ B) ∧ ¬B

  • D.

    (A ∨ B) ∧ ¬A ∧ B

  • 我的答案:

    --

  • 正确答案:

    A

  • 答案解析:

    【答案】A
    【解析】:对于选项 A,逻辑表达式为 (A ∧ B) ∨ (¬A ∧ B)。

    1. 我们可以对表达式进行提取公因子的化简:
      (A ∧ B) ∨ (¬A ∧ B) = B ∧ (A ∨ ¬A)
    2. 根据逻辑恒等式,(A ∨ ¬A) 恒等于 True。
    3. 因此,该表达式化简为 B ∧ True,即 B。
14.
  1. 一个 n 个顶点的强连通图最少有几条边( )
  • A.

    n

  • B.

    n+1

  • C.

    n-1

  • D.

    n*(n-1)

  • 我的答案:

    --

  • 正确答案:

    A

  • 答案解析:

    【答案】A
    【解析】: 边数最少的强连通图即形成一个“环”。此时边数最小,为 n

15.
  1. 定义一个数是 “好的”:当且仅当这个数是个六位数(允许有前导零),并且里面含有数字 9,那么符合“好的”条件的数的个数是( )。
  • A.

    531441

  • B.

    1000000

  • C.

    99999

  • D.

    468559

  • 我的答案:

    --

  • 正确答案:

    D

  • 答案解析:

    【答案】D
    【解析】:由题意,六位数(允许前导零)可以看作 6 个数字的序列,每个位置有 10 种选择,共有 10⁶ = 1,000,000 个数字。

    • 不含数字 9 的数,每位只能选 0~8 中的数字,即 9 种选择,故个数为 9⁶ = 531,441。
    • 因此,含有数字 9 的“好的”数的个数为:
      10⁶ − 9⁶ = 1,000,000 − 531,441 = 468,559。

[组合题]

1.
#include <iostream>
using namespace std;
int f(int n, int m) {
    if (n == 1) return m;
    if (m == 1) return n;
    int res = 0;
    for (int i = 1; i < n; i++)
        for (int j = 1; j < m; j++)
            res += f(i, j);
    return res;
}
int n, m;
int main() {
    cin >> n >> m;
    cout << f(n, m) << endl;
    return 0;
}
1.

计算f(n,m)的时间复杂度为O(nm)。( )

  • 正确
  • 错误
2.

去掉第4行的代码,程序将会不停地递归调用而不会返回结果。( )

  • 正确
  • 错误
3.

同时去掉第4行和第5行的代码,程序将会不停地递归调用而不会返回结果。( )

  • 正确
  • 错误
4.

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

  • A.

    92

  • B.

    143

  • C.

    166

  • D.

    175

5.

当去掉程序中的第4行,且输入为3 6时,输出为( )。

  • A.

    0

  • B.

    7

  • C.

    25

  • D.

    43

  • 我的答案:

    --、--、--、--、--

  • 正确答案:

    错误、错误、错误、D、B

  • 答案解析:

    1.

    --

    2.

    --

    3.

    --

    4.

    --

    5.

    --

2.
#include <iostream>
using namespace std;
int c[100], n, s, cnt, ans;
void calln(int x) {
    while (x) {
        n++;
        x >>= 1;
    }
}
int bitcount(int x) {
    int cnt = 0;
    while (x) {
        cnt += x & 1;
        x >>= 1;
    }
    return cnt;
}
int main() {
    cin >> s;
    calln(s);
    for (int i = s; i; i = s & (i-1)) {
        cnt++;
        c[bitcount(i)] += i;
    }
    for (int i = 1; i <= n; i++)
        ans = max(ans, c[i]);
    cout << cnt << endl;
    cout << ans << endl;
    return 0;
}

假设输入的 s 为正整数且不超过 10910^9,完成下面的判断题和单选题:

1.

输出的第一行不会超过输入的 s。( )

  • 正确
  • 错误
2.

bitcount(x) 函数用于计算 x 对应的二进制整数的位数。( )

  • 正确
  • 错误
3.

输入的 s 不应大于 100,否则会发生数组越界。( )

  • 正确
  • 错误
4.

当输入的 s 为 23 时,输出的第一行整数为( )。

  • A.

    3

  • B.

    7

  • C.

    15

  • D.

    31

5.

当输入的 s 为 11 时,输出的第二行整数为( )。

  • A.

    11

  • B.

    16

  • C.

    19

  • D.

    22

6.

当输入的 s 为 127 时,输出的第二行整数为( )。

  • A.

    1980

  • B.

    2540

  • C.

    2870

  • D.

    3200

  • 我的答案:

    --、--、--、--、--、--

  • 正确答案:

    正确、错误、错误、C、D、B

  • 答案解析:

    1.

    --

    2.

    --

    3.

    --

    4.

    --

    5.

    --

    6.

    --

3.
#include <iostream>
using namespace std;
int f[1001], g[1001], p[1001], m, n;
void init() {
    f[1] = g[1] = 1;
    for (int i = 2; i <= 1000; i++) {
        if (!f[i]) {
            p[++m] = i;
            for (int j = i*i; j <= 1000; j += i)
                f[j] = 1;
        }
        g[i] = g[i-1] + f[i];
    }
}
int main() {
    init();
    cin >> n;
    cout << f[n] << endl;
    cout << g[n] << endl;
    if (n <= 100)
        cout << p[n] << endl;
    return 0;
}
1.

第 16 行执行结束后,m 的值为 500。( )

  • 正确
  • 错误
2.

第 16 行执行结束后,f[103] 的值为 0。( )

  • 正确
  • 错误
3.

g[1000] + m 等于 1000。( )

  • 正确
  • 错误
4.

当输入为 123 时,输出的第一行为( )。

  • A.

    0

  • B.

    1

  • C.

    33

  • D.

    123

5.

当输入为 30 时,输出的第二行为( )。

  • A.

    10

  • B.

    15

  • C.

    20

  • D.

    25

6.

当输入为 25 时,输出的第三行为( )。

  • A.

    93

  • B.

    97

  • C.

    101

  • D.

    103

  • 我的答案:

    --、--、--、--、--、--

  • 正确答案:

    错误、正确、正确、B、C、B

  • 答案解析:

    1.

    init() 函数调用结束后,m 的值为 1 ∼ 1000 范围内素数的个数,虽然我们不能很快得出这个结果,但是容易发现 1 ∼ 1000 范围内素数的个数肯定比非素数的个数要少,所以 m 不可能是 500 。

    2.

    init() 函数调用结束后,所以素数 i 对应的 f [i] 均为 0,所有非素数 i 对应的 f [i] 均为 1。因为 103 是素数,所以 f [103] = 0。

    3.

    g[1000] 表示的是 1 ∼ 1000 中非素数的个数, m 表示的是 1 ∼ 1000 中素数的个数,所以 g[1000] + m 等于 1000。

    4.

    因为 123 不是素数,所以 f [123] = 1。

    5.

    g[30] 表示 1 ∼ 30 范围内非素数的个数,1 ∼ 30 范围内共有 20 个非素数,所以g[30] = 20。

    6.

    p[i] 表示第 i 个素数,我们可以依次列举出前 25 个素数:2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,可得第 25 个素数 p[25] = 97。

[组合题]

1.

给定一个由 1n1 \sim n 构成的排列 aa,求 aa 的上一个排列。比如,当 nn 等于 3 时,由 131 \sim 3 构成的全排列按照从小到大排如下所示:

1,2,3
1,3,2
2,1,3
2,3,1
3,1,2
3,2,1

其中,排列 3,2,1 的上一个排列为 3,1,2;排列 3,1,2 的上一个排列为 2,3,1;排列 2,3,1 的上一个排列为 2,1,3;排列 2,1,3 的上一个排列为 1,3,2;排列 1,3,2 的上一个排列为 1,2,3;排列 1,2,3 没有上一个排列。

你的任务是根据输入的排列计算并输出其上一个排列;

特别地,若输入的排列没有上一个排列,输出 -1 。试补全下面的模拟上一个排列的程序。

#include <iostream>	
#include <algorithm>	
using namespace std;	
int n, a[1000];	
bool cmp(int a, int b) {	
    return (1);	
}	
bool pre_permutation(int a[], int n) {
    int i = n-1;	
    while (i > 0 && a[i-1] < a[i])	
        i--;	
    if ((2))	
        return false;	
    for (int j = i; j < n; j++) {	
        if (j == n-1 || (3)) {
            swap((4), a[j]);	
            break;	
        }	
    }	
    sort((5), a+n, cmp);	
    return true;	
}	
int main() {	
    cin >> n;	
    for (int i = 0; i < n; i++)	
        cin >> a[i];	
    if (pre_permutation(a, n)) {	
        for (int i = 0; i < n; i++)	
            cout << a[i] << " ";	
    }	
    else {	
        cout << -1 << endl;	
    }	
    return 0;	
}	
1.

(1)处应填()

  • A.

    a == b

  • B.

    a > b

  • C.

    a < b

  • D.

    a + b

2.

(2)处应填( )

  • A.

    !i

  • B.

    i = 1

  • C.

    i == 1

  • D.

    i > 1

3.

(3)处应填( )

  • A.

    a[j] == a[i]

  • B.

    a[j] < a[j+1]

  • C.

    a[j+1] > a[i-1]

  • D.

    a[j+1] > a[i]

4.

(4)处应填( )

  • A.

    a[0]

  • B.

    a[i-1]

  • C.

    a[i]

  • D.

    a[j+1]

5.

(5)处应填()

  • A.

    a[i]

  • B.

    a+i-1

  • C.

    a+i

  • D.

    a+j

  • 我的答案:

    --、--、--、--、--

  • 正确答案:

    B、A、C、B、C

  • 答案解析:

    1.

    --

    2.

    --

    3.

    --

    4.

    --

    5.

    --

2.

某科技公司有 nn 名工程师需要配备高性能工作站。公司为这次采购预留了 AA 元的预算。与此同时,第 ii 位工程师有自己的个人设备采购基金 MiM_i 元。

市场上有 B(Bn)B(B ≥ n) 款不同型号的工作站可供选择,第 jj 款工作站的价格为 CjC_j 元。每位工程师可以使用自己的个人基金或公司的预算资金来购买工作站,但财务规定要求:
1、每位工程师只能为自己购买工作站
2、不同工程师之间的资金不能相互借用
公司需要知道最多能为多少名工程师配备工作站
请设计一个算法,计算在满足预算约束的情况下,最多可以有多少名工程师获得工作站。

#include <iostream>
using namespace std;
#define MAXN 1000000
int n, B, A, M[MAXN], C[MAXN], l, r, ans, mid;
bool check(int nn) {
    int count = 0, i, j;
    i = ___(1)___;
    j = 1;
    while (i <= n) {
        if (___(2)___)
            count += C[j] - M[i];
        i++;
        j++;
    }
    return ___(3)___;
}
void sort(int a[], int l, int r) {
    int i = l, j = r, x = a[(l + r) / 2], y;
    while (i <= j) {
        while (a[i] < x) i++;
        while (a[j] > x) j--;
        if (i <= j) {
            y = a[i];
            a[i] = a[j];
            a[j] = y;
            i++;
            j--;
        }
    }
    if (i < r) sort(a, i, r);
    if (l < j) sort(a, l, j);
}
int main() {
    int i;
    cin >> n >> B >> A;
    for (i = 1; i <= n; i++)
        cin >> M[i];
    for (i = 1; i <= B; i++)
        cin >> C[i];
    sort(M, 1, n);
    sort(C, 1, B);
    l = 0;
    r = n;
    while (l <= r) {
        mid = (l + r) / 2;
        if (___(4)___) {
            ans = mid;
            l = mid + 1;
        } else
            r = ___(5)___;
    }
    cout << ans << endl;
    return 0;
}

1.

(1)处应该填( )

  • A.

    n-nn+1

  • B.

    0

  • C.

    nn+n-1

  • D.

    n

2.

(2)处应该填( )

  • A.

    M[j]<C[i]

  • B.

    M[i]<C[i]

  • C.

    M[i]<C[j]

  • D.

    M[j]<C[j]

3.

(3)处应该填( )

  • A.

    count <= A

  • B.

    count <= B

  • C.

    count <= n

  • D.

    count <= nn

4.

(4)处应该填( )

  • A.

    check(mid+1)

  • B.

    !check(mid+1)

  • C.

    !check(mid)

  • D.

    check(mid)

5.

(5)处应该填( )

  • A.

    mid

  • B.

    mid-1

  • C.

    mid+1

  • D.

    mid+2

  • 我的答案:

    --、--、--、--、--

  • 正确答案:

    A、C、A、D、B

  • 答案解析:

    1.

    --

    2.

    --

    3.

    --

    4.

    --

    5.

    --