[CSP-J 2022] 直播获奖

45次阅读
没有评论

共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。

# 题面
NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为 w%,即当前排名前 w% 的选手的最低成绩就是即时的分数线。

更具体地,若当前已评出了 p 个选手的成绩,则当前计划获奖人数为 max(1,⌊p×w%⌋),其中 w 是获奖百分比,⌊x⌋ 表示对 x 向下取整,max(x,y) 表示 x 和 y 中较大的数。如有选手成绩相同,则所有成绩并列的选手都能获奖,因此实际获奖人数可能比计划中多。

作为评测组的技术人员,请你帮 CCF 写一个直播程序。

输入描述

第一行有两个整数 n,w。分别代表选手总数与获奖率。
第二行有 n 个整数,依次代表逐一评出的选手成绩。

输出描述

只有一行,包含 n 个非负整数,依次代表选手成绩逐一评出后,即时的获奖分数线。相邻两个整数间用一个空格分隔。

样例

输入 1

10 60
200 300 400 500 600 600 0 300 200 100

输出 1

200 300 400 400 400 500 400 400 300 300

输入 2

10 30
100 100 600 100 100 100 100 100 100 100

输出 2

100 100 600 600 600 600 100 100 100 100

数据范围

各测试点的 n 如下表:

测试点编号n=
1∼310
4∼6500
7∼102000
11∼1710^4
18∼2010^5

对于所有测试点,每个选手的成绩均为不超过 600 的非负整数,获奖百分比 w 是一个正整数且 1≤w≤99。

在计算计划获奖人数时,如用浮点类型的变量(如 C/C++ 中的 float、double,Pascal 中的 real、double、extended 等)存储获奖比例 w,则计算 5×60% 时的结果可能为 3.000001,也可能为 2.999999,向下取整后的结果不确定。因此,建议仅使用整型变量,以计算出准确值。

样例 1 解释

[CSP-J 2022] 直播获奖

注意,在第 9 名选手的成绩评出之后,计划获奖人数为 5 人,但由于有并列,因此实际会有 6 人获奖。

答案

#pragma GCC optimize(3, "Ofast", "inline")
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool cmp(int a, int b){return a > b;}

int main(){ios::sync_with_stdio(false);
    cin.tie(0);
    int n, w;
    cin >> n >> w;
    vector<int> grades;
    while(n--){
        int g;
        cin >> g;
        grades.insert(upper_bound(grades.begin(), grades.end(), g, cmp), g);
        int m = max(1,int(grades.size()*w/100))-1;
        //cout << "m=" << m << endl;
        //for(int a : grades) cout << a << " ";
        //cout << endl;
        cout << grades[m] << " ";
        //cout << endl;
    }
    return 0;
}

题目标签和答案实现并无直接联系。如本体标签为桶排序,但我选择插入排序实现,也可以 AC。

实际考试建议使用桶排序,排序的时间复杂度为 O(n),耗时较短,但是找到分数线要遍历一次桶数组(600 个元素),耗时较长。

而插入排序(本实现使用 STL algorithm 库中 lower_bound 二分查找左边界)的时间复杂度为 O(n log n),耗时较长,同时,插入的时间复杂度为 O(n),耗时较长,但是找到分数线仅需计算索引即可(O(1)),极快。

但是综合来看,桶排的优势更明显。

(我这么做纯粹因为比较简单)

正文完
 0
元素
版权声明:本站原创文章,由 元素 于2024-10-23发表,共计1499字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码