#CSPJSH30. 珅泽教育CSP-J第一轮模拟考第三十套

珅泽教育CSP-J第一轮模拟考第三十套

珅泽教育CSP-J第一轮模拟考第三十套

本卷共43题,满分100分。程序阅读题和完善程序题的每个小题均配有完整的共用程序。

一、单项选择题(共15题,每题2分,共30分;每题有且仅有一个正确选项)

第 1 题

计算机的内存与外存相比,内存( )。

{{ select(1) }}

  • 容量更大
  • 断电时数据会丢失
  • 存取速度更快
  • 价格更便宜

第 2 题

多长的 double 数组,大小是1 MB?( )

{{ select(2) }}

  • 128
  • 8192
  • 131072
  • 262144

第 3 题

执行下列代码,最终输出的 sum 是( )。

int x = 3;
int y = ++x;
int z = y++;
int sum = x + y + z;
printf("%d", sum);

{{ select(3) }}

  • 12
  • 13
  • 14
  • 15

第 4 题

输入13时,下面程序输出( )。

int i = 0, t;
cin >> t;
do {
    t = t & (t - 1);
    i++;
} while (t);
cout << i;

{{ select(4) }}

  • 1
  • 2
  • 3
  • 4

第 5 题

下面代码的输出是( )。

#include <iostream>
using namespace std;

struct STU {
    char name[20];
    int age;
    char sex;
    char num[20];
};
int main() {
    struct STU stu[5] = {{"小红", 6, 'F', "xt1666"},
                         {"小明", 9, 'M', "xt1888"},
                         {"小王", 7, 'F', "xt1999"}};
    struct STU *p = stu;
    cout << (p + 2)->age << " " << (p + 2)->num;
    return 0;
}

{{ select(5) }}

  • 9 x
  • 9 xt1888
  • 7 x
  • 7 xt1999

第 6 题

两个8位二进制补码 1000101001110010 相加的结果是( )。

{{ select(6) }}

  • 1011 1000
  • 0011 1000
  • 1011 0011
  • 1111 1100

第 7 题

八进制数 527 在( )进制下是 157

{{ select(7) }}

  • 十二
  • 十六

第 8 题

下图最能体现哪一种程序调用思想?( )

第8题递归图

{{ select(8) }}

  • 递归
  • 模拟
  • 枚举
  • 贪心

第 9 题

对数组 {7,13,5,18,6,1,27,9} 自左向右进行降序冒泡排序,会发生( )次交换。

{{ select(9) }}

  • 12
  • 13
  • 14
  • 15

第 10 题

某算法满足 T(n)=T(n/2)+n,且 T(1)=1,其时间复杂度是( )。

{{ select(10) }}

  • O(logn)O(log n)
  • O(n)O(n)
  • O(nlogn)O(n log n)
  • O(n2)O(n^2)

第 11 题

双向链表中,每个结点分别用 priornext 指向先驱和后继。删除指针 p 指向的结点,可以使用( )。

{{ select(11) }}

  • p->next=p->next->next; p->next->prior=p;
  • p->prior=p->prior->prior; p->prior->next=p;
  • p->next->prior=p->prior; p->prior->next=p->next;
  • p->next->prior=p; p->prior->next=p;

第 12 题

有向图的邻接矩阵如下,顶点4的入度和出度分别是( )。

1 0 1 0 0 1
1 1 0 1 1 0
0 1 0 0 1 1
0 0 1 1 1 0
0 1 1 1 1 0
1 0 0 1 1 1

{{ select(12) }}

  • 3,4
  • 4,3
  • 3,5
  • 5,3

第 13 题

前缀表达式 -+a*bc+de 的后缀表达式是( )。

{{ select(13) }}

  • ab+c*d-e+
  • ab+c*de+-
  • abc*+de+-
  • abc*+d-e+

第 14 题

A、B、C、D、E、F六个人排成一排,A必须在B左边,C必须在D左边(不要求相邻),共有( )种排法。

{{ select(14) }}

  • 720
  • 360
  • 180
  • 96

第 15 题

全校2023名同学每人分别有7到2029支花,人数与花数一一对应。每人用3支或4支花做一束,并使花束总数尽量多。所有人一共做了多少个4支花束?

{{ select(15) }}

  • 2020
  • 2023
  • 2026
  • 2029

二、程序阅读题(每个小题单独作答,共40分)

程序阅读(1):方阵旋转

输入的 n,m 均不超过500;每次操作给出中心 (a,b)、半径 r 与方向 opt

#include <cstdio>
int g[510][510], tot, f[510][510];
int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            g[i][j] = ++tot;
    for (int i = 1; i <= m; i++){
        int a, b, r, opt;
        scanf("%d %d %d %d", &a, &b, &r, &opt);
        if (opt == 0){
            for (int i = a - r; i <= a + r; i++)
                for (int j = b - r; j <= b + r; j++)
                    f[a - b + j][a + b - i] = g[i][j];
            for (int i = a - r; i <= a + r; i++)
                for (int j = b - r; j <= b + r; j++)
                    g[i][j] = f[i][j];
        }
        if (opt == 1){
            for (int i = a - r; i <= a + r; i++)
                for (int j = b - r; j <= b + r; j++)
                    f[a + b - j][b - a + i] = g[i][j];
            for (int i = a - r; i <= a + r; i++)
                for (int j = b - r; j <= b + r; j++)
                    g[i][j] = f[i][j];
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++)
            printf("%d ", g[i][j]);
        printf("\n");
    }
    return 0;
}

第 16 题

opt=0 表示逆时针旋转90度。( )

{{ select(16) }}

  • 正确
  • 错误

第 17 题

把第8行 g[i][j]=++tot 改为 g[i][j]=tot++,程序结果不会改变。( )

{{ select(17) }}

  • 正确
  • 错误

第 18 题

a,b 必须满足 1<=a-r<=a+r<=n1<=b-r<=b+r<=n。( )

{{ select(18) }}

  • 正确
  • 错误

第 19 题

a=b=n/2+1,旋转会让所选奇数阶方阵的中心元素保持不动,其余元素换位。( )

{{ select(19) }}

  • 正确
  • 错误

第 20 题

程序旋转的是以第 a 行、第 b 列为中心的( )阶方阵。

{{ select(20) }}

  • 2r+1
  • 2r-1
  • 2r
  • r

第 21 题

n=5,m=3,三次操作依次为 2 2 1 03 3 1 14 4 1 0 时,最终矩阵第4行是( )。

{{ select(21) }}

  • 11 6 1 4 5
  • 13 2 23 8 3
  • 16 7 24 17 18
  • 12 9 14 19 10

二、程序阅读题(每个小题单独作答,共40分)

程序阅读(2):最小二乘法

程序拟合直线 y=ax+b

#include <bits/stdc++.h>
using namespace std;
int NUM_SAMPLES;
void least_squares(double x[], double y[], double& a, double& b) {
    double sum_x = 0, sum_y = 0, sum_xy = 0, sum_x_squared = 0;
    for (int i = 1; i <= NUM_SAMPLES; i++) {
        sum_x += x[i];
        sum_y += y[i];
        sum_xy += x[i] * y[i];
        sum_x_squared += x[i] * x[i];
    }
    double denominator = NUM_SAMPLES * sum_x_squared - sum_x * sum_x;
    a = (NUM_SAMPLES * sum_xy - sum_x * sum_y) / denominator;
    b = (sum_x_squared * sum_y - sum_x * sum_xy) / denominator;
}
int main() {
    double x[105], y[105], a, b;
    scanf("%d", &NUM_SAMPLES);
    for(int i = 1; i <= NUM_SAMPLES; i++)
        scanf("%lf %lf", &x[i], &y[i]);
    least_squares(x, y, a, b);
    printf("a = %.1lf, b = %.1lf\n", a, b);
    return 0;
}

第 22 题

程序可能因为分母为0,得到 infNaN 等非有限结果。( )

{{ select(22) }}

  • 正确
  • 错误

第 23 题

程序第4行参数中的 & 是取地址运算符。( )

{{ select(23) }}

  • 正确
  • 错误

第 24 题

程序计算得到的 ab 可以同时为 0.0。( )

{{ select(24) }}

  • 正确
  • 错误

第 25 题

n=100x[i]=y[i]=i 时,程序输出( )。

{{ select(25) }}

  • a = 1, b = 1
  • a = 1.0, b = 1.0
  • a = 1, b = 0
  • a = 1.0, b = 0.0

第 26 题

输入4个点 (-1,0),(1,2),(2,3),(10,11) 时,输出( )。

{{ select(26) }}

  • a = 1, b = 1
  • a = 1.0, b = 1.0
  • a = 1, b = 0
  • a = 1.0, b = 0.0

第 27 题

输入3个点 (-1,10),(1,5),(3,1.5) 时,a,b 的符号是( )。

{{ select(27) }}

  • a>0,b<0
  • a>0,b>0
  • a<0,b<0
  • a<0,b>0

二、程序阅读题(每个小题单独作答,共40分)

程序阅读(3):区间次大值

输入满足 n,q<=100000-10^9<=a[i]<=10^91<=L<=R<=n。这里的“次大值”允许与最大值相等。

#include <bits/stdc++.h>
using namespace std;
int n, q, a[100005], dp[100005][20][2];
void init(){
    for (int i = 1; (1 << i) <= n; i++){
        for (int L = 1; L + (1 << i) - 1 <= n; L++){
            dp[L][i][0] = max(dp[L][i - 1][0], dp[L + (1 << (i - 1))][i - 1][0]);
            dp[L][i][1] = min(
                max(dp[L][i - 1][1], dp[L + (1 << (i - 1))][i - 1][0]),
                max(dp[L][i - 1][0], dp[L + (1 << (i - 1))][i - 1][1])
            );
        }
    }
}
int query(int L, int R){
    int a = -2e9, b = -2e9, M = 0;
    while (L + (1 << (M + 1)) - 1 <= R) M++;
    for (int i = M; i >= 0; i--){
        if (L + (1 << i) - 1 > R) continue;
        if (dp[L][i][0] > a){
            b = max(a, dp[L][i][1]);
            a = dp[L][i][0];
        }
        else b = max(b, dp[L][i][0]);
        L += (1 << i);
    }
    return b;
}
int main(){
    scanf("%d%d", &n, &q);
    for (int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        dp[i][0][0] = a[i];
        dp[i][0][1] = -2e9;
    }
    init();
    while (q--){
        int L, R; scanf("%d%d", &L, &R);
        printf("%d\n", query(L, R));
    }
    return 0;
}

第 28 题

程序输出的数可能是 -2000000000。( )

{{ select(28) }}

  • 正确
  • 错误

第 29 题

对任意查询 query(L,R),一定有返回值严格小于区间最大值。( )

{{ select(29) }}

  • 正确
  • 错误

第 30 题

init()query() 的最坏时间复杂度分别最接近( )。

{{ select(30) }}

  • O(n),O(logn)O(n),O(log n)
  • O(nlogn),O(logn)O(n log n),O(log n)
  • O(n),O(n)O(n),O(n)
  • O(nlogn),O(n)O(n log n),O(n)

第 31 题

输入如下时,输出是( )。

4 2
1 3 2 4
1 3
2 4

{{ select(31) }}

  • 1 2
  • 2 3
  • 3 3
  • 3 4

第 32 题

n=10a[i]=i,并查询全部45个长度大于1的区间时,所有输出之和是( )。

{{ select(32) }}

  • 280
  • 285
  • 380
  • 385

第 33 题

同样查询全部45个区间,若结果 x 恰好输出26次,则数组中大于等于 x 的数最少出现( )次。

{{ select(33) }}

  • 1
  • 2
  • 3
  • 4

三、完善程序题(单项选择题,共30分)

完善程序(1):两组组合和

从两组长度为 n 的数据中各取 m 个数,求最小的公共组合和。

#include <bits/stdc++.h>
using namespace std;
int n, m, t;
int a[20], b[20], s1[1 << 15], s2[1 << 15];
void dfs(int cnt, int pos, int sum1, int sum2) {
    if (___(1)___) {
        s1[++t] = sum1;
        s2[t] = sum2;
        return;
    }
    if (___(2)___) return;
    dfs(___(3)___);
    dfs(cnt, pos + 1, sum1, sum2);
}
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= n; i++) cin >> b[i];
    dfs(___(4)___);
    sort(s1 + 1, s1 + t + 1);
    sort(s2 + 1, s2 + t + 1);
    int i = 1, j = 1;
    while (___(5)___) {
        if (s1[i] == s2[j]) {
            cout << s1[i];
            return 0;
        }
        if (s1[i] < s2[j]) i++;
        else j++;
    }
    cout << "IMPOSSIBLE";
    return 0;
}

第 34 题

①处应填( )。

{{ select(34) }}

  • cnt == m
  • cnt == n
  • pos == m
  • pos == n

第 35 题

②处应填( )。

{{ select(35) }}

  • m-pos+1<n-cnt
  • n-pos+1<m-cnt
  • n-pos+1<=m-cnt
  • m-pos+1<=n-cnt

第 36 题

③处应填( )。

{{ select(36) }}

  • cnt+1,pos,sum1+a[pos],sum2+b[pos]
  • cnt+1,pos+1,sum1,sum2
  • cnt+1,pos+1,sum1+a[pos],sum2+b[pos]
  • cnt+1,pos,sum1,sum2

第 37 题

④处应填( )。

{{ select(37) }}

  • 0,0,0,0
  • 1,1,0,0
  • 1,0,0,0
  • 0,1,0,0

第 38 题

⑤处应填( )。

{{ select(38) }}

  • i<=t && j<=t
  • i<=t && j<t
  • i<=t || j<t
  • i<=t || j<=t

三、完善程序题(单项选择题,共30分)

完善程序(2):无向图最短环

图无自环、无重边,要求返回最短环长度;不存在环时返回 -1

#include <bits/stdc++.h>
using namespace std;

int n;
vector<vector<int>> g(1005);

int findShortestCycle() {
    int ans = (___(2)___);
    int vis[1005] = {0};
    int dist[1005];
    int fa[1005];
    memset(dist, 0x3f, sizeof dist);
    for (int i = 0; i < n; i++) {
        memset(vis, 0, sizeof vis);
        memset(fa, -1, sizeof fa);
        queue<int> q;
        q.push(i);
        fa[i] = i;
        vis[i] = (___(3)___);
        dist[i] = 0;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int j = 0; j < g[x].size(); j++) {
                int y = g[x][j];
                if (!vis[y]) {
                    q.push(y);
                    dist[y] = dist[x] + 1;
                    (___(4)___);
                    vis[y] = i + 1;
                    continue;
                }
                if (vis[y] == i + 1 && y != fa[x]) {
                    ans = (___(5)___);
                }
            }
        }
    }
    ans = (ans == 1e9 ? -1 : ans);
    return ans;
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        (___(1)___);
    }
    cout << findShortestCycle();
    return 0;
}

第 39 题

①处应填( )。

{{ select(39) }}

  • g[v].push_back(u)
  • 不填
  • g[u].emplace(v)
  • g[v].push(u)

第 40 题

②处应填( )。

{{ select(40) }}

  • 1e9
  • 0
  • 0x80808080
  • 1

第 41 题

③处应填( )。

{{ select(41) }}

  • 1
  • i
  • i+1
  • 0

第 42 题

④处应填( )。

{{ select(42) }}

  • fa[y]=x
  • fa[x]=y
  • fa[x]=x
  • fa[y]=y

第 43 题

⑤处应填( )。

{{ select(43) }}

  • min(dist[x]+dist[y]+1,ans)
  • max(dist[x]+dist[y]+1,ans)
  • min(dist[x]-dist[y]-1,ans)
  • min(dist[y]-dist[x]+1,ans)