#4707. 2025年 CSP-J初赛模拟题 (八)

2025年 CSP-J初赛模拟题 (八)

单项选择题(每题只有一个正确选项,每题2分,共30分)

  1. 在互联网中,我们通过域名就能获得对应的 IP 地址依靠的是 {{ select(1) }}
  • ARP
  • MAC
  • DNS
  • TCP
  1. C++ 中,不能作为函数重载判断依据的是 {{ select(2) }}
  • 返回类型
  • 参数类型
  • 参数个数
  • 参数顺序
  1. 根节点高度为 1,一棵拥有 512 个节点的二叉树的高度至少为 {{ select(3) }}
  • 8
  • 10
  • 11
  • 9
  1. 王老师最近在给班上的同学安排午餐食谱,要求一份食谱里要有3种荤菜和1种素菜,或有2种荤菜和2种素菜,如果总共有6种荤菜和4种素菜可选,则王老师最多可以设计出多少种食谱 {{ select(4) }}
  • 90
  • 152
  • 170
  • 180
  1. 12 人排成一列纵队,并从前往后依次编号为 1-12 号。现在要求大家打乱重新排序成一个与原有序列不同的方式,并重新按序编号。请找出有多少种方案,使得所有人的新号码与原始号码相差不超过 1。{{ select(5) }}
  • 155
  • 227
  • 232
  • 239
  1. 以下哪个不是 C++ 中的关键字 {{ select(6) }}
  • int
  • static
  • friend
  • priority
  1. 一个链表中,每一个结点有一个 next 指针指向下一个结点,现在想要删除链表中结点 p 的下一个结点,正确的操作是?{{ select(7) }}
  • free(p->next);
  • temp = p->next; p->next = temp->next; free(temp);
  • temp = p->next; temp->next = p->next; free(temp);
  • temp = p->next; free(temp);
  1. 入栈顺序为 1,2,3,4,5,则不可能的出栈顺序为 {{ select(8) }}
  • 1 2 3 4 5
  • 5 4 3 2 1
  • 3 2 1 5 4
  • 3 1 2 4 5
  1. 李老师要将野营活动中的 10 位同学分成扎营、做饭、探路 3 组,要求每组之间人数相差不能超过两人,请问李老师有几种分配方案 {{ select(9) }}
  • 4200
  • 8400
  • 22050
  • 44100
  1. 王妈妈每天都会开车去接小王放学回家,晚上 5:30 王妈妈出发,6:00 到达学校,且小王刚好放学,接到小王后两人 6:30 准时到家。但今天小王提前放学,王妈妈并不知道,小王自己先走路回家,两人在 5:55 分时见面并启程返回(假定所有的相关的移动都是匀速运动),那么两人今天到家的时间是 {{ select(10) }}
  • 6:15
  • 6:20
  • 6:25
  • 6:30
  1. 以下哪个不属于线性结构 {{ select(11) }}
  • 队列
  • 线性表
  1. (原码反码补码)以下哪个编码不能表示数字 0 {{ select(12) }}
  • [00000000]反
  • [11111111]反
  • [10000000]补
  • [10000000]原
  1. 一个二叉树的后序遍历序列为 BEDCA,中序遍历序列为 BADEC,则先序遍历序列为: {{ select(13) }}
  • ABCDE
  • ABDCE
  • ABCED
  • ABDEC
  1. 定义了一个数组 int A[8],那么 &A[5] 的值和哪一项相等 {{ select(14) }}。
  • A+160
  • A+40
  • A + 5
  • A + 20
  1. 假设 a = true, b = true, c = false,则逻辑运算表达式为真的是 {{ select(15) }}
  • (a∧c)∨(b∧c)
  • (a∨c)∧(b∧c)
  • (a∧c)∨(b∧a)
  • a ∧ (b ∨ c) ∧ c

程序阅读理解题(共3大题。程序输入不超过数组或字符串定义的范围,除特殊说明外,判断题1.5分,选择题3分,共计40分)

#include<bits/stdc++.h>
using namespace std;
int sum[10000];
int apple(int m,int n){
    if(m==0||m==1||n==1)
        return 1;
    if(m<n)
        return apple(m,m);
    if(m>=n)
        return apple(m-n,n)+apple(m,n-1);
}
int main(){
    int n,m,s;
    cin>>s;
    for(int i=1;i<=s;i++) {
        cin>>m>>n;
        sum[i]=apple(m,n);
    }
    for(int j=1;j<=s;j++)
        cout<<sum[j]<<endl;
    return 0;
}

题目保证输入均为正整数

判断题

  1. apple(5,3) 的结果比 apple(4,3) 小 {{ select(16) }}
  1. 第 5 行的 if 中应该改为加入对 n==0 的判定,否则会导致程序无法运行出结果(2分){{ select(17) }}

选择题

  1. 当输入的 m,n 为 8,9 时,apple 函数被调用的次数是 {{ select(18) }}
  • 29
  • 31
  • 46
  • 47
  1. 当输入的 m,n 为 9,8 时,apple 函数被调用的次数是 {{ select(19) }}
  • 57
  • 59
  • 61
  • 63
#include <iostream>
using namespace std;
int main(){
    int l, r, mod = 10;
    cin >> l >> r;
    int ans = 0;
    for(int i = l; i <= r; i++){
        int temp = i;
        int last = -1;
        bool flag = true;
        while(temp){
            int now = temp % mod;
            if(last == 2 && now == 6){
                flag = false;
            }
            last = now;
            temp /= mod;
        }
        if(flag)
            ans++;
    }
    cout << ans << endl;
}

输入保证 r 大于等于 l,且 l,r 均为正数。

判断题

  1. 若取消第 8 行,并将所有 temp 全部替换成 i,程序一定可以运行出结果,但是结果可能会错。 {{ select(20) }}
  1. 若将第 9 行 last 的初始值改为 1,则程序运行结果一定不变。 {{ select(21) }}
  1. 最终输出的值不可能大于 r-l。 {{ select(22) }}

选择题

  1. 如果输入为 100 300,则运行结果为 {{ select(23) }}
  • 200
  • 199
  • 198
  • 201
  1. 如果输入为 1 10000,则运行结果为 {{ select(24) }}
  • 9700
  • 9701
  • 7000
  • 7001
  1. 若将第 4 行中 mod 改为 6,输入为 1 100000,则运行结果为 {{ select(25) }}
  • 0
  • 66666
  • 97000
  • 100000
#include<bits/stdc++.h>
using namespace std;
int n,k,m;
string s;
int xh()
{
    if(s[1]=='(') return 2;
    for(int i=2;i<(int)s.length();i++)
        if(s[i]=='(') return 3;
    return 1;
}
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
int main()
{
    scanf("%d",&n);
    cin>>s;
    int opt=xh();
    if(opt==1){
        m=1;
        for(int i=1;i<(int)s.length();i++)
        {
            m*=10;
            k=k*10+(s[i]-'0');
        }
        n=n*(m/gcd(k,m));
        printf("%d/%d",n+k/gcd(k,m),m/gcd(k,m));
    }
    else if(opt==2)
    {
        for(int i=2;i<(int)s.length()-1;i++)
        {
            m=m*10+9;
            k=k*10+(s[i]-'0');
        }
        n=n*(m/gcd(k,m));
        printf("%d/%d",n+k/gcd(k,m),m/gcd(k,m));
    }
    else if(opt==3)
    {
        int no=0,i;
        for(i=1;i<(int)s.length();i++)
            if(s[i]!='(')
            {
                no=no*10+(s[i]-'0');
                k=k*10+(s[i]-'0');
            }
            else break;
        int j=i-1;
        for(i=i+1;i<(int)s.length()-1;i++)
        {
            k=k*10+(s[i]-'0');
            m=m*10+9;
        }
        for(i=1;i<=j;i++) m=m*10;
        k-=no;
        n=n*(m/gcd(k,m));
        printf("%d/%d",n+k/gcd(k,m),m/gcd(k,m));
    }
    return 0;
}

假设输入的是个小数,且如果有括号,则括号内表示无限循环部分

判断题

  1. 若将头文件更换为 include<cstdio>,程序不能正常运行 {{ select(26) }}
  1. 假如程序输入的是 1.25,则程序的输出为 125/100(2分) {{ select(27) }}
  1. 若将第 49 行中 s.length()-1 改为 s.length(),则程序可能会越界 {{ select(28) }}

选择题

  1. 将 12 行 {} 中的内容改为以下哪一项,程序将不能正确执行(4分) {{ select(29) }}
  • return y?gcd(y,x%y):x;
  • return y>0?gcd(y,x%y):x:
  • if(y) return gcd(y,x%y);else return x;
  • if(x%y) return y,else return gcd(y,x%y);
  1. 输入 1.(3),得到的结果是()(4分) {{ select(30) }}
  • 13/100
  • 8/6
  • 130/1000
  • 4/3
  1. 输入 0.168(5),得到的结果是()(4分) {{ select(31) }}
  • 1516/9000
  • 1517/9000
  • 1518/9000
  • 1519/9000

程序完善题(共2大题,每个选择题3分,共计30分)

(求众数)给出一个数字 nn,接下来给出 nn 个数字,求这 nn 个数字中出现次数最多的数字。

提示:先排序数组,使得所有相同的数字在连续的一段。然后统计每一段数字的长度,最长的长度对应的数字即为众数。

#include <iostream>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
int main(){
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    sort(a + 1, a + 1 + n);
    int max_time = 0, cnt = 0, ans;
    for(int i = 1; i <= n; i++){
        if(**1**){
            cnt++;
        }else{
            if(cnt > max_time){
                max_time = cnt;
                **2**;
            }
            **3**;
        }
    }
    if(cnt > max_time)
        **4**;
    cout << **5** << endl;
}
  1. 1 处应填 {{ select(32) }}
  • a[i] != a[i-1]
  • a[i] == a[i-1]
  • a[i] > max_time
  • a[i] < max_time
  1. 2 处应填 {{ select(33) }}
  • ans = max_time
  • cnt = 0
  • ans = a[i]
  • ans = a[i-1]
  1. 3 处应填 {{ select(34) }}
  • ans = max_time
  • cnt = 0
  • cnt = 1
  • ans = a[i]
  1. 4 处应填 {{ select(35) }}
  • ans = max_time
  • ans = a[i]
  • cnt = 1
  • ans = a[n]
  1. 5 处应填 {{ select(36) }}
  • ans
  • cnt
  • max_time
  • a[n]

(数组选数)给定一个大小为 n 的数组和一个数字 k,问能否从这些数字中取到一些数字使得其和为 k。若能,输出 YES,否则输出 NO。 输入第一行包含两个正整数 n,k,接下来一行包含 n 个正整数,表示数组的内容。

提示:使用分治的思想来做,将数组切割成多段子数组。对于每一段子数组,都新建一个 bool 类型的 ans 数组用于保存每个数字能否被取到,再合并多段子数组算出的 ans 数组,最终合并成一个总的 ans 数组,判断 ans[k] 是否为 1,则可以得到答案。

#include <iostream>
#include <vector>
using namespace std;
int a[25], n, k;
vector<bool> dfs(int l, int r){
    vector<bool>ans(k + 1);
    int mid = (l + r) / 2;
    **1**;
    if(l > r) return ans;
    if(l == r){
        if(a[l] <= k)
            **2**;
        return ans;
    }
    vector<bool>lans = dfs(l, mid);
    vector<bool>rans = dfs(mid + 1, r);
    **3**{ //将 lans 和 rans 的内容合并成一个 ans 数组并返回
        if(lans[i] == 0) continue;
        ans[i] = 1;
        for(int j = 0; j <= k; j++){
            if(rans[j] == 0) continue;
            **4**;
        }
    }
    return ans;
}
int main(){
    cin >> n >> k;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
    }
    vector<bool>ans = **5**;
    if(ans[k]){
        cout << "YES" << endl;
    }else{
        cout << "NO" << endl;
    }
}
  1. 1 处应填 {{ select(37) }}
  • ans[0] = 1
  • ans[l] = 1
  • ans[mid] = 1
  • ans[r] = 1
  1. 2 处应填 {{ select(38) }}
  • return
  • ans[a[l]] = 1
  • ans[l] = 1
  • return ans
  1. 3 处应填 {{ select(39) }}
  • for(int i = 1; i <= n; i++)
  • for(int i = l; i <= r; i++)
  • for(int i = 0; i <= k; i++)
  • for(int i = a[l]; i <= a[r]; i++)
  1. 4 处应填 {{ select(40) }}
  • ans[j] = 1
  • ans[a[j]] = 1
  • ans[i+j] = 1
  • ans[i+a[j]] = 1
  1. 5 处应填 {{ select(41) }}
  • dfs(n, k)
  • dfs(0, n)
  • dfs(1, n)
  • dfs(0, n-1)