1

2018年山东CSP-X复赛真题解析

​欢迎大家订阅我的专栏:算法题解:C++与Python实现
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:历年CSP-X复赛真题解析 | 汇总


B4072 小明的照片

【题目来源】

洛谷:B4072 [CSP-X 2018] 小明的照片 - 洛谷

【题目描述】

国庆假期,小明和爸爸妈妈一起外出旅游,沿途拍摄了很多美丽的风景照片,在返程的前一天晚上,他整理了一下所有的照片:手机里有 \(x\) 张,平板电脑里有 \(y\) 张,单反相机里有 \(z\) 张。小明计划开学后拿出 \(n\) 张照片与同学们分享,请问他至少还需要再拍摄多少张照片?

【输入】

一行,四个正整数 \(n,x,y,z\),中间用空格隔开。

输入的数据保证现有的照片总数不超过 \(n\)

【输出】

一行,只有一个整数,表示还需要再拍摄的照片数量。

【输入样例】

30 8 2 10

【输出样例】

10

【算法标签】

《洛谷 B4072 小明的照片》 #CSP-X小学组# #2018# #山东#

【代码详解】

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

int n;  // 总数
int x;  // 第一类数量
int y;  // 第二类数量
int z;  // 第三类数量

int main()
{
    // 输入总数和三类数量
    cin >> n >> x >> y >> z;
    
    /**
     * 计算并输出剩余数量:
     * 总数减去三类已知数量
     * 用于计算未被分类的数量
     */
    cout << n - x - y - z << endl;
    
    return 0;  // 程序正常结束
}

【运行结果】

30 8 2 10
10

B4073 快递费用

【题目来源】

洛谷:B4073 [CSP-X 2018] 快递费用 - 洛谷

【题目描述】

某快递公司按邮寄物品的重量收费,收费标准如下:

重量在 \(500\) 克以内的,一律 \(20\) 元;

超过 \(500\) 克的,超重的部分按每 \(500\) 克加收费用。超出的重量不足 \(500\) 克的,按 \(500\) 克计算。例如:\(1020\) 克,超重 \(520\) 克,需加收两份费用。

根据目的地的不同,加收的费用是不一样的。快递公司划分了五个目的地区域:

  • 区域 \(1\):每超重 \(500\) 克加收 \(4\) 元;
  • 区域 \(2\):每超重 \(500\) 克加收 \(6\) 元;
  • 区域 \(3\):每超重 \(500\) 克加收 \(9\) 元;
  • 区域 \(4\):每超重 \(500\) 克加收 \(10\) 元;
  • 区域 \(5\):每超重 \(500\) 克加收 \(17\) 元。

给出物品的重量 \(w\) 和目的地区域编号 \(n\),请你计算快递费用。

【输入】

一行,两个正整数 \(w,n\)

【输出】

一行,一个整数,表示快递费用。

【输入样例】

1020 3

【输出样例】

38

【算法标签】

《洛谷 B4073 快递费用》 #CSP-X小学组# #2018# #山东#

【代码详解】

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

int w;                  // 输入的总重量(单位:克)
int a[6] = {0, 4, 6, 9, 10, 17};  // 不同包裹类型对应的价格数组
int n;                  // 包裹类型(1-5)
int ans;                // 最终计算的总价格
int t;                  // 计算所需的包裹数量

int main()
{
    // 输入总重量和包裹类型
    cin >> w >> n;
    
    // 初始化基础价格为20元
    ans = 20;
    
    // 扣除首重500克
    w -= 500;
    
    // 计算超出部分所需的500克单位数量
    t = w / 500;
    
    // 如果有余数,需要多算一个单位
    if (w % 500)
    {
        t++;
    }
    
    // 计算总价格:基础价格 + 超重部分价格
    ans += t * a[n];
    
    // 输出最终价格
    cout << ans;
    
    return 0;
}

【运行结果】

1020 3
38

B4074 统计成绩

【题目来源】

洛谷:[B4074 CSP-X 2018] 统计成绩 - 洛谷

【题目描述】

考试结束之后,每位同学都依据成绩获得相应的等级:

  • 优秀:\(90\sim 100\)
  • 良好:\(80\sim 89\)
  • 及格:\(60\sim79\)
  • 不及格:\(60\) 以下。

现在,需要统计一下获得每个等级的人数分别是多少。

【输入】

第一行,一个正整数 \(n\),表示总人数。

第二行,\(n\) 个由空格隔开的整数,表示每个同学的成绩(\(0\sim100\))。

【输出】

共四行,每行一个整数,依次表示获得优秀、良好、及格、不及格等级的人数。

【输入样例】

10 
93 33 86 81 47 82 84 92 73 94

【输出样例】

3
4
1
2

【算法标签】

《洛谷 B4074 统计成绩》 #CSP-X小学组# #2018# #山东#

【代码详解】

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

int n;          // 学生人数
int a, b, c, d; // 四个等级的人数统计
// a: 90分及以上
// b: 80-89分
// c: 60-79分
// d: 60分以下

int main()
{
    // 输入学生人数
    cin >> n;
    
    // 遍历每个学生的成绩
    for (int i = 1; i <= n; i++)
    {
        int x;  // 学生成绩
        cin >> x;
        
        // 根据成绩等级进行统计
        if (x >= 90)        // 90分及以上
        {
            a++;
        }
        else if (x >= 80)   // 80-89分
        {
            b++;
        }
        else if (x >= 60)   // 60-79分
        {
            c++;
        }
        else                // 60分以下
        {
            d++;
        }
    }
    
    // 输出各等级人数,每个等级一行
    cout << a << endl;  // 90分及以上人数
    cout << b << endl;  // 80-89分人数
    cout << c << endl;  // 60-79分人数
    cout << d << endl;  // 60分以下人数
    
    return 0;
}

【运行结果】

10
93 33 86 81 47 82 84 92 73 94
3
4
1
2

B4075 11 的倍数

【题目来源】

洛谷:[B4075 CSP-X 2018] 11 的倍数 - 洛谷

【题目描述】

如何判断一个正整数 \(x\) 是不是 \(3\) 的倍数?

可以计算 \(x\div3\) 所得的余数,如果余数等于 \(0\),那么 \(x\)\(3\) 的倍数。

还可以用下面的方法来判断:

\(x\) 的个位数字、十位数字、百位数字……相加,如果所得的和是 \(3\) 的倍数,那么 \(x\) 就是 \(3\) 的倍数。例如:\(x = 8511\)\(8+5+1+1=15\)\(15\)\(3\) 的倍数,那么 \(8511\) 就是 \(3\) 的倍数。
接下来你的任务是,判断 \(x\) 是不是 \(11\) 的倍数。

有一个与判断是不是 \(3\) 的倍数类似的方法供你参考:

  • \(x\) 的个位、百位、万位……上的数字求和,得 \(s_1\)
  • \(x\) 的十位、千位、十万位……上的数字求和,得 \(s_2\)

如果 \(s_1\div11\) 所得的余数 \(= s_2\div11\) 所得的余数,那么 \(x\) 就是 \(11\) 的倍数。
例如:\(x=3162819\)\(s_1 = 3+6+8+9 = 26\)\(s_2 = 1+2+1 = 4\)。因为 \(26\div11\)\(4\)\(4\div11\) 也余 \(4\),所以 \(3162819\)\(11\) 的倍数。

【输入】

第一行,一个正整数 \(n\)

以下 \(n\) 行,每行一个正整数 \(x_i\),需要你判断 \(x_i\) 是不是 \(11\) 的倍数。

【输出】

\(n\) 行,每行输出一个 \(\texttt{Yes}\)\(\texttt{No}\),表示 \(x_i\) 是不是 \(11\) 的倍数。

【输入样例】

3 
2035 
62202 
335 

【输出样例】

Yes
No
No

【算法标签】

《洛谷 B4075 11的倍数》 #CSP-X小学组# #2018# #山东#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n;  // 存储测试用例的数量
string s;  // 存储输入的数字字符串

// 检查字符串t是否满足"奇偶位数字和模11同余"的条件
bool check(string t)
{
    int s1 = 0, s2 = 0;  // s1: 偶数位(索引为0,2,4,...)的数字和, s2: 奇数位(索引为1,3,5,...)的数字和
    
    // 遍历字符串t的每个字符
    for (int i = 0; i < t.size(); i++)
    {
        if (i % 2 == 0)  // 如果是偶数位
            s1 += t[i] - '0';  // 将该位的数字加到s1
        else  // 如果是奇数位
            s2 += t[i] - '0';  // 将该位的数字加到s2
    }
    
    // 检查s1和s2对11取模的结果是否相同
    return s1 % 11 == s2 % 11;
}

int main()
{
    cin >> n;  // 输入测试用例的数量
    
    // 处理每个测试用例
    while (n--)
    {
        cin >> s;  // 输入一个数字字符串
        
        // 检查字符串s是否满足条件
        if (check(s)) 
            cout << "Yes" << endl;  // 满足条件则输出"Yes"
        else 
            cout << "No" << endl;  // 不满足条件则输出"No"
    }
    
    return 0;
}

【运行结果】

3
2035
Yes
62202
No
335
No
posted @ 2026-01-20 15:43  热爱编程的通信人  阅读(1)  评论(0)    收藏  举报