CCF CSP 202109赛题练习
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CCF CSP 202109赛题练习相关的知识,希望对你有一定的参考价值。
CCF CSP 赛题练习
CCF202109-1 数组推导
题目描述
A1,A2,…,An是一个由 n个自然数(即非负整数)组成的数组。在此基础上,我们用数组B1…Bn表示A的前缀最大值。
B i = m a x A 1 , A 2 , . . . , A i Bi=max\\A1,A2,...,Ai\\
Bi=maxA1,A2,...,Ai
如上所示,Bi定义为数组A中前i个数的最大值。
根据该定义易知A1=B1,且随着i的增大,Bi单调不降。
此外,我们用sum=A1+A2+…+An表示数组A中n个数的总和。
现已知数组B,我们想要根据B的值来反推数组A。
显然,对于给定的B,A的取值可能并不唯一。
试计算,在数组A所有可能的取值情况中,sum的最大值和最小值分别是多少?
输入格式
从标准输入读入数据。
输入的第一行包含一个正整数n。
输入的第二行包含n个用空格分隔的自然数B1,B2,…,Bn。
输出格式
输出到标准输出。
输出共两行。
第一行输出一个整数,表示sum的最大值。
第二行输出一个整数,表示sum的最小值。
样例1输入
6
0 0 5 5 10 10
样例1输出
30
15
样例1解释
数组A的可能取值包括但不限于以下三种情况。
情况一:A = [0, 0, 5, 5, 10, 10]
情况二:A = [0, 0, 5, 3, 10, 4]
情况三:A = [0, 0, 5, 0, 10, 0]
其中第一种情况 sum = 30 为最大值,第三种情况 sum = 15 为最小值。
#include<bits/stdc++.h>
int main()
int n, b, last = -1, sum = 0, sum2 = 0, i;
scanf("%d", &n);
for (i = 1; i <= n; i++)
scanf("%d", &b);
sum += b;
if (b != last)
sum2 += b;
last = b;
printf("%d\\n%d\\n", sum, sum2);
问题分析:
需要计算B数组之和,B数组不重复数之和。
由于B单调递增,用C/C++和Java语言程序中,去除重复只需要前后元素进行比较就可以了。最小值一律取0
这个题没有必要用数组来存储读入的数据,读入数据流中的数据进行计算处理就可以了。
CCF CSP-202012-1期末预测之安全指数
题意概述
给出 n 项指标,每项指标包含 s c o r e i score_i scorei和 w i w_i wi两个值,求 m a x ( 0 , ∑ i = 1 n s c o r e i ⋅ w i ) max(0,\\sum_i=1^n score_i\\cdot w_i) max(0,∑i=1nscorei⋅wi)的值。
输入输出格式
输入的第一行包含一个正整数 n。接下来 n 行,每行包含用空格分隔的两个整数,分别表示指标的重要程度和小菜同学该项的得分。
输出一个非负整数,表示小菜同学期末的安全指数。
数据规模
2 < = n < = 1 0 5 2<=n<=10^5 2<=n<=105
C++代码
#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main()
ios::sync_with_stdio(false);
cin.tie(0);
gg ni, w, s;
cin >> ni;
gg ans = 0;
while (ni--)
cin >> w >> s;
ans += s * w;
cout << max(0ll, ans) << "\\n";
return 0;
【CCF CSP-202012-2】期末预测之最佳阈值
题意概述
给出 m 位同学的安全指数 y i y_i yi和挂科情况 r e s u l t i ( r e s u l t i ∈ 0 , 1 ) result_i(result_i\\in \\0,1\\) resulti(resulti∈0,1),选择一个阈值 θ \\theta θ,其预测正确的次数为 y < θ y<\\theta y<θ且 r e s u l t i = = 0 result_i==0 resulti==0的同学个数与 y > = θ y>=\\theta y>=θ且 r e s u l t i = = 1 result_i==1 resulti==1的同学个数之和。求出满足以下条件的 θ \\theta θ:
- 最佳阈值仅在 y i y_i yi中选取,即与某位同学的安全指数相同;
- 按照该阈值对这 m 位同学上学期的挂科情况进行预测,预测正确的次数最多(即准确率最高);
- 多个阈值均可以达到最高准确率时,选取其中最大的。
输入输出格式
输入的第一行包含一个正整数 m。接下来 m行,每行包含用空格分隔的两个整数,分别为 y i y_i yi和 r e s u l t i result_i resulti,含义如上文所述。
输出一个整数,表示最佳阈值。
数据规模
2 < = m < = 1 0 5 2<=m<=10^5 2<=m<=105
算法设计
将这 m 位同学的
y
i
y_i
yi和挂科情况
r
e
s
u
l
t
i
(
r
e
s
u
l
t
i
∈
0
,
1
)
result_i(result_i\\in \\0,1\\)
resulti(resulti∈0,1)存储到一个map<gg, array<gg, 2>> r
中,其中键表示
y
i
y_i
yi,值表示对应挂科情况的同学数量。遍历map
,统计出
θ
\\theta
θ恰好为
y
i
y_i
yi时的预测正确的次数,求出最大的即可。这里的关键在于如何求出
θ
\\theta
θ恰好为
y
i
y_i
yi时的预测正确的次数。我们可以定义变量p0
表示小于
y
i
y_i
yi且
r
e
s
u
l
t
i
=
=
0
result_i==0
resulti==0的同学个数;定义变量p1
表示小于
y
i
y_i
yi且
r
e
s
u
l
t
i
=
=
1
result_i==1
resulti==1的同学个数,那么
θ
\\theta
θ恰好为
y
i
y_i
yi时的预测正确的次数就是
p
0
+
m
−
p
1
p0+m-p1
p0+m−p1,而p0
、p1
可以在遍历过程中进行累加。
C++代码
#include <bits/stdc++.h>
using namespace std;
using gg = long long;
int main()
ios::sync_with_stdio(false);
cin.tie(0);
map<gg, array<gg, 2>> r;
gg mi, y, res;
cin >> mi;
for (gg i = 0; i < mi; ++i)
cin >> y >> res;
r[y][res]++;
gg p0 = 0, p1 = 0, ans = 0, c = 0;
for (auto& i : r)
gg t = p0 + mi - p1;
if (t >= c)
c = t;
ans = i.first;
p0 += i.second[0];
p1 += i.second[1];
cout << ans << "\\n";
return 0;
C语言代码
利用数组存储yi及result_i
,利用双重for循环,暴力设定阈值。
#include<bits/stdc++.h>
using namespace std;
using gg = long long;
int main()
int m, i, j, y, count = 0, x = 0;
cin >> m;
int s[m][3];
for (i = 0; i < m; i++)
cin >> s[i][0] >> s[i][1];
s[i][2] = 0;
for (i = 0; i<m; i++)
y = s[i][0];
for (j = 0; j < m; j++)
if (s[j][0] < y && s[j][1] == 0) s[i][2]++;
else if (s[j][0] >= y && s[j][1] == 1) s[i][2]++;
for (i = 0; i < m; i++)
if (s[i][2] > count)
count = s[i][2];
x=s[i][0];
else if (s[i][2] == count && s[i][0] > x)
x = s[iCCF CSP-2022-01 赛题练习