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

浙公网安备 33010602011771号