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=1nscoreiwi)的值。

输入输出格式

输入的第一行包含一个正整数 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(resulti0,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 θ

  1. 最佳阈值仅在 y i y_i yi中选取,即与某位同学的安全指数相同;
  2. 按照该阈值对这 m 位同学上学期的挂科情况进行预测,预测正确的次数最多(即准确率最高);
  3. 多个阈值均可以达到最高准确率时,选取其中最大的。

输入输出格式

输入的第一行包含一个正整数 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(resulti0,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+mp1,而p0p1可以在遍历过程中进行累加。

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 赛题练习

CCF-CSP 202209 赛题练习

CCF-CSP 201712 赛题训练

CCF-CSP 201604 赛题训练

CCF-CSP 201612 赛题训练

CCF-CSP 201609 赛题训练