1

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

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

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

适合人群:

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

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


B4076 随机数

【题目来源】

洛谷:[B4076 CSP-X2019 山东] 随机数 - 洛谷

【题目描述】

光头强和熊大熊二在玩随机数比大小的游戏。具体规则如下:平板电脑会提供三个 \(1\sim 6\) 范围内的数字,分别交由熊大、熊二和光头强,数字大的人获胜。现在熊大和熊二已经拿到了随机数,请问光头强取得哪几个数字,才能获胜?

注意:如果光头强的数字与熊大熊二的数字相同,也算光头强获胜。

【输入】

一行,两个正整数 \(x,y\),中间用空格隔开,表示熊大熊二的数字。

【输出】

一行,若干个整数,表示光头强的数字。按照从小到大的顺序输出,相邻的数之间用一个空格隔开。

【输入样例】

4 2

【输出样例】

4 5 6

【算法标签】

《洛谷 B4076 随机数》 #CSP-X小学组# #2019# #山东#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int x, y;  // 定义两个整数变量x和y

int main()
{
    cin >> x >> y;  // 从标准输入读取两个整数x和y
    
    int maxn = max(x, y);  // 计算x和y中的最大值
    
    // 从maxn开始,到6结束,依次输出每个数字
    for (int i = maxn; i <= 6; i++)
        cout << i << " ";  // 输出数字和一个空格
    
    cout << endl;  // 输出换行符
    
    return 0;  // 程序正常结束
}

【运行结果】

4 2
4 5 6

B4077 鼓掌

【题目来源】

洛谷:[B4077 CSP-X2019 山东] 鼓掌 - 洛谷

【题目描述】

运动会上,两个班级在为场上的运动员鼓掌加油。其中 A 班的同学每 \(x\) 秒钟鼓掌一次,B 班的同学每 \(y\) 秒钟鼓掌一次,每次鼓掌都持续 \(1\) 秒钟。这样的话,在 \(n\) 秒钟之内,共有多少秒的时间有掌声?

\(x=2,y=3,n=10\) 的情况如下:

1 2 3 4 5 6 7 8 9 10
A A A A A
B B B

共 7 秒有掌声。

【输入】

一行,三个正整数 \(x,y,n\)

【输出】

一行,一个整数,表示有掌声的时间总长度。

【输入样例】

2 3 10

【输出样例】

7

【算法标签】

《洛谷 B4077 鼓掌》 #CSP-X小学组# #2019# #山东#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int x, y, n;  // 定义三个整数变量x, y, n

// 计算最大公约数函数
int gcd(int a, int b)
{
    return b ? gcd(b, a % b) : a;  // 使用辗转相除法计算最大公约数
}

int main()
{
    cin >> x >> y >> n;  // 输入三个整数x, y, n
    
    // 计算在1到n范围内能被x或y整除的数的个数
    // 公式:能被x整除的数的个数 + 能被y整除的数的个数 - 能同时被x和y整除的数的个数
    // 能同时被x和y整除的数的个数 = 能被x和y的最小公倍数整除的数的个数
    // 最小公倍数 = x * y / 最大公约数(x, y)
    cout << n / x + n / y - n / (x * y / gcd(x, y)) << endl;
    
    return 0;
}

【运行结果】

2 3 10
7

B4078 统计成绩

【题目来源】

洛谷:B4078 [CSP-X2019 山东] 统计成绩 - 洛谷

【题目描述】

\(n\) 位同学参加了期中考试,考试共有 \(m\) 门课程。

考试结束之后,老师想知道:每位同学有几门课程达到或超过了课程的班级平均分?

现在,请你帮忙统计一下。

【输入】

第一行,两个正整数 \(n,m\)\(n\) 表示学生总人数,\(m\) 表示课程数量。

接下来 \(n\) 行,每行 \(m\) 个整数,表示一位同学的成绩。

【输出】

\(n\) 行,每行一个整数,表示该同学达到或超过平均分的课程数量。

【输入样例】

5 3 
81 80 86  
55 74 79  
92 47 99  
50 65 41  
42 61 74

【输出样例】

3
2
2
0
0

【算法标签】

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

【代码详解】

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

int n, m, ans;          // n: 学生人数, m: 科目数量, ans: 每科达平均分的人数
int a[105][25];          // 存储每个学生每科的成绩
double b[105];           // 存储每科的平均分

int main()
{
    // 输入学生人数和科目数量
    cin >> n >> m;
    
    // 输入每个学生每科的成绩,并累加每科的总分
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> a[i][j];
            b[j] += a[i][j];  // 累加第j科的总分
        }
    }

    // 计算每科的平均分
    for (int i = 1; i <= m; i++)
    {
        b[i] /= n;  // 第i科总分除以学生人数得到平均分
    }

    // 统计每个学生达平均分的科目数量
    for (int i = 1; i <= n; i++)
    {
        ans = 0;  // 重置计数器
        for (int j = 1; j <= m; j++)
        {
            if (a[i][j] >= b[j])  // 如果该科成绩达到或超过平均分
            {
                ans++;  // 计数加1
            }
        }
        cout << ans << endl;  // 输出该学生达平均分的科目数量
    }
    
    return 0;
}

【运行结果】

5 3 
81 80 86  
55 74 79  
92 47 99  
50 65 41  
42 61 74
3
2
2
0
0

B4079 金币

【题目来源】

洛谷:[B4079 CSP-X2019 山东] 金币 - 洛谷

【题目描述】

乔治在梦中来到了一个神奇部落,这个部落的神树具有奇特的功能:对于每一位新朋友,都会获赠金币,而且金币的数量会随时间的延续而增加:

  • \(1\) 周,每天 \(1\) 枚金币;
  • \(2\) 周,每天 \(2\) 枚金币;
  • \(3\) 周,每天 \(3\) 枚金币;
  • ……

请问:至少多少天,乔治的金币数量达到 \(n\) 枚?

【输入】

一行,只有一个正整数 \(n\)

【输出】

一行,一个整数,表示金币达到 \(n\) 枚所需的最少天数。

【输入样例】

30

【输出样例】

17

【算法标签】

《洛谷 B4079 金币》 #二分# #CSP-X小学组# #2019# #山东#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long  // 将int重新定义为long long类型
int n, ans;  // n: 输入的天数, ans: 当前计算的总训练次数

signed main()  // 因为使用了#define int long long, 所以用signed main
{
    cin >> n;  // 输入总天数
    
    int t = 1;  // 当前周期数,每个周期包含若干天
    while (1)  // 无限循环
    {
        ans += 7 * t;  // 计算到第t个周期的总训练次数,每个周期训练7*t次
        if (ans > n) break;  // 如果总训练次数超过n,跳出循环
        t++;  // 进入下一个周期
    }
    
    // 输出结果
    // (t-1)*7: 前面完整周期的总天数
    // 7 - (ans-n)/t: 当前周期中的第几天
    // ans-n: 超出n的训练次数
    // (ans-n)/t: 需要回退的天数
    cout << (t - 1) * 7 + 7 - (ans - n) / t << endl;
    
    return 0;
}

【运行结果】

30
17
posted @ 2026-01-20 15:49  热爱编程的通信人  阅读(0)  评论(0)    收藏  举报