#1485. CSP-J 2023 初赛试题

CSP-J 2023 初赛试题

CSP-J 2023 初赛试题(广东省68分)

一、单选题(每题 2 分,共 30 分)

第 1 题 在 C++ 中,下面哪个关键字用于声明一个变量,其值不能被修改?

{{ select(1) }}

  • unsigned
  • const
  • static
  • mutable

第 2 题 八进制数 12345670₈07654321₈ 的和为:

{{ select(2) }}

  • 22222221₈
  • 21111111₈
  • 22111111₈
  • 22222211₈

第 3 题 阅读下述代码,修改 datavalue 成员以存储 3.14,正确的方式是:

union Data { int num; float value; char symbol; };
union Data data;

{{ select(3) }}

  • data.value = 3.14;
  • value.data = 3.14;
  • data->value = 3.14;
  • value->data = 3.14;

第 4 题 假设有一个链表的节点定义如下,现在有一个指向链表头部的指针 Node* head。如果想要在链表中插入一个新节点,其成员 data 的值为 42,并使新节点成为链表的第一个节点,下面哪个操作是正确的?

struct Node { int data; Node* next; };
Node* head;
Node* newNode = new Node;  
newNode->data = 42;  
newNode->next = head;  
head = newNode;
Node* newNode = new Node;  
head->data = 42;  
newNode->next = head;  
head = newNode;
Node* newNode = new Node; 
newNode->data = 42; 
head->next = newNode;
Node* newNode = new Node; 
newNode->data = 42; 
newNode->next = head;

{{ select(4) }}

  • 1
  • 2
  • 3
  • 4

第 5 题 一棵拥有 2023 个节点的三叉树高度至少为()。

{{ select(5) }}

  • 6
  • 7
  • 8
  • 9

第 6 题 小明在某一天中依次有七个空闲时间段,他想要选出至少一个空闲时间段来练习唱歌,但他希望任意两个练习的时间段之间都有至少两个空闲的时间段让他休息,则小明一共有( )种选择时间段的方案。。

{{ select(6) }}

  • 31
  • 18
  • 21
  • 33

第 7 题 关于高精度运算,错误的说法是:

{{ select(7) }}

  • 处理大整数或多位小数
  • 大整数除以小整数的步骤描述
  • 高精度乘法时间仅与较长数位数有关
  • 加法需处理进位

第 8 题 后缀表达式 6 2 3 + - 3 8 2 / + * 2 ^ 3 + 对应的中缀表达式是:

{{ select(8) }}

  • ((6-(2+3))*(3+8/2))^2+3
  • 6-2+3*3+8/2^2+3
  • (6-(2+3))*((3+8/2)^2)+3
  • 6-((2+3)*(3+8/2))^2+3

第 9 题 二进制 101010₂ 和八进制 166₈ 的和为:

{{ select(9) }}

  • 10110000₂
  • 236₈
  • 158₁₀
  • A0₁₆

第10题 假设有一组字符 {a,b,c,d,e,f},对应的频率分别为5%、9%、12%、13%、16%、45%。请问以下哪个选项是字符a-f分别对应的一组哈夫曼编码?

{{ select(10) }}

  • 1111,1110,101,100,110,0
  • 1010,1001,1000,011,010,00
  • 000,001,010,011,10,11
  • 1010,1011,110,111,00,01

第11题 给定一棵二叉树,其前序遍历结果为ABDECFG,中序遍历结果为DEBACFG。请问这棵树的正确后序遍历结果是什么?

{{ select(11) }}

  • EDBGFCA
  • EDGBFCA
  • DEBGFCA
  • DBEGFCA

第12题 考虑一个有向无环图,包含4条有向边:(1,2)(1,3)(2,4)(3,4)。以下哪个选项是这个图的有效拓扑排序?

{{ select(12) }}

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

第13题 在计算机中,以下哪个选项描述的数据存储容量最小?

{{ select(13) }}

  • 字节 (byte)
  • 比特 (bit)
  • 字 (word)
  • 千字节 (kilobyte)

第14题 一个班级有10个男生和12个女生。要选出3人小组且至少包含1个女生,有多少种组合?

{{ select(14) }}

  • 1420
  • 1770
  • 1540
  • 2200

第15题 以下哪个不是操作系统?

{{ select(15) }}

  • Linux
  • Windows
  • Android
  • HTML

二、阅读程序(共三题,共40分)​

第 16 题 (分值​:12 分)

#include<iostream>
#include<cmath>
using namespace std;

double f(double a,double b,double c){
    double s=(a+b+c)/2;
    return sqrt(s*(s-a)*(s-b)*(s-c));
}
int main(){
   cout.flags(ios::fixed);
   cout.precision(4);
   
   int a,b,c;
   cin>>a>>b>>c;
   cout<<f(a,b,c)<<endl;
   return 0;
}

假设输入的所有数都为不超过 1000 的正整数。

判断题

1. 输入2 2 2时输出1.7321

{{ select(16) }}

  • 正确
  • 错误
2. 交换(s-b)*(s-c)顺序不影响结果

{{ select(17) }}

  • 正确
  • 错误
3. 程序总是输出四位小数

{{ select(18) }}

  • 正确
  • 错误
    单选题
4. 输入3 4 5时输出

{{ select(19) }}

  • 6.0000
  • 12.0000
  • 24.0000
  • 30.0000
5. 输入5 12 13时输出

{{ select(20) }}

  • 24.0000
  • 30.0000
  • 60.0000
  • 120.0000

第17题(阅读程序) (共13.5)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int f(string x,string y){
    int m=x.size();
    int n=y.size();
    vector<vector<int>>v(m+1,vector<int>(n+1,0));
    for(int i=1;i<=m;i++){
       for(int j=1;j<=n;j++){
            if(x[i-1]==y[j-1]){
                v[i][j]=v[i-1][j-1]+1;
            }else{
                v[i][j]=max(v[i-1][j],v[i][j-1]);
            }
        }
    }
    return v[m][n];
}
bool g(string x,string y){
    if(x.size() != y.size()){
        return false;
    }
    return f(x+x,y)==y.size();
}
int main(){
    string x,y;
    cin>>x>>y;
    cout<<g(x,y)<<endl;
    return 0;
}

判断题

1. f返回值 ≤ min(m,n)

{{ select(21) }}

  • 正确
  • 错误
2. f返回最长公共子串长度

{{ select(22) }}

  • 正确
  • 错误
3. 相同字符串时g返回true

{{ select(23) }}

  • 正确
  • 错误

单选题

4. 替换v[m][n]v[n][m]

{{ select(24) }}

  • 行为不变
  • 只会改变输出
  • 一定非正常退出
  • 可能非正常退出
5. 输入csp-j p-jcs输出

{{ select(25) }}

  • 0
  • 1
  • T
  • F
6. 输入csppsc spsccp输出

{{ select(26) }}

  • T
  • F
  • 0
  • 1

第18题(阅读程序)(共14.5分)

#include <iostream>
#include <cmath>
using namespace std;

int solve1(int n){
    return n*n;
}

int solve2(int n){
   int sum=0;
   for(int i=1;i<=sqrt(n);i++){
        if(n%i==0){
            if(n/i==i){//第13行
                sum+=i*i;//第14行
            }else{
                sum+=i*i+(n/i)*(n/i);
            }
        }
    }
    return sum;
}
int main(){
    int n;
    cin>>n;
    cout<<solve2(solve1(n))<<" "<<solve1((solve2(n)))<<endl;
    return 0;
}

判断题

1. solve2计算因子平方和

{{ select(27) }}

  • 正确
  • 错误
2. 第13-14行避免重复计算

{{ select(28) }}

  • 正确
  • 错误
3. 质数n时返回n²+1

{{ select(29) }}

  • 正确
  • 错误

单选题

4. (4分)如果输入的 n 为质数 p 的平方,那么 solve2(n) 的返回值为( )

{{ select(30) }}

  • p² + p + 1
  • n² + n + 1
  • n² + 1
  • p⁴ + 2p² + 1
5.当输入为正整数时,第一项减去第二项的差值一定()

{{ select(31) }}

  • 大于 0
  • 大于等于 0 且不一定大于 0
  • 小于 0
  • 小于等于 0 且不一定小于 0
6. 输入5时输出

{{ select(32) }}

  • 651 625
  • 650 729
  • 651 676
  • 652 625

三、​完善程序(共两题,共30分)

第19题(完善程序:寻找被移除的元素)

问题描述:原有长度为 n+1、公差为 1 的等差数列,将数列输入到程序的数组时移除了一个元素,导致长度为 n 的连续数组可能不再连续(除非被移除的是第一个或最后一个元素)。需要在数组不连续时,找出被移除的元素。

#include <iostream>
#include <vector>
using namespace std;
int find_missing(vector<int>& nums) {
    int left = 0, right = nums.size() - 1;
    while (left < right){
        int mid = left + (right - left) / 2;
        if (nums[mid] == mid + ①) {
            ②;
        } else {
            ③;
        }
    }
    return ④;
}
int main() {
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++) cin >> nums[i];
    int missing_number = find_missing(nums);
    if (missing_number == ⑤) {
        cout << "Sequence is consecutive" << endl;
    }else{
        cout << "Missing number is " << missing_number << endl;
    }
    return 0;
}

①处应填( )

{{ select(33) }}

  • 1
  • nums[0]
  • right
  • left

②处应填( )

{{ select(34) }}

  • left = mid + 1
  • right = mid - 1
  • right = mid
  • left = mid

③处应填( )

{{ select(35) }}

  • left = mid + 1
  • right = mid - 1
  • right = mid
  • left = mid

④处应填( )

{{ select(36) }}

  • left + nums[0]
  • right + nums[0]
  • mid + nums[0]
  • right + 1

⑤处应填( )

{{ select(37) }}

  • nums[0] + n
  • nums[0] + n - 1
  • nums[0] + n + 1
  • nums[n - 1]

第20题(完善程序 编辑距离 )

题目:给定两个字符串,每次操作可以选择删除(Delete)、插入(Insert)、替换(Replace),一个字符,求将第一个字符串转换为第二个字符串所需要的最少操作次数。

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int min(int x, int y, int z) {
    return min(min(x, y), z);
}
int edit_dist_dp(string str1, string str2) {
    int m = str1.length();
    int n = str2.length();
    vector<vector<int>> dp(m + 1, vector<int>(n + 1));
    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0)
                dp[i][j] = ①;
            else if (j == 0)
                dp[i][j] = ②;
            else if (③)
                dp[i][j] = ④;
            else
                dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j], ⑤);
        }
    }
    return dp[m][n];
}
int main() {
    string str1, str2;
    cin >> str1 >> str2;
    cout << "Mininum number of operation:" << edit_dist_dp(str1, str2) << endl;
    return 0;
}
1. ①处应填( )

{{ select(38) }}

  • j
  • i
  • m
  • n
2. ②处应填( )

{{ select(39) }}

  • j
  • i
  • m
  • n
3. ③处应填( )

{{ select(40) }}

  • str1[i-1]==str2[j-1]
  • str1[i]==str2[j]
  • str1[i-1]!=str2[j-1]
  • str1[i]!=str2[j]
4. ④处应填( )

{{ select(41) }}

  • dp[i-1][j-1]+1
  • dp[i-1][j-1]
  • dp[i-1][j]
  • dp[i][j-1]
5. ⑤处应填( )

{{ select(42) }}

  • dp[i][j] + 1
  • dp[i-1][j-1]+1
  • dp[i-1][j-1]
  • dp[i][j]