[CSP-J2020 T2] 直播获奖
题目描述:NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为 w%,即当前排名前 w% 的选手的最低成绩就是即时的分数线。更具体地,若当前已评出了 p 个选手的成绩,则当前计划获奖人数为 max(1,⌊p×w%⌋),其中 w 是获奖百分比,⌊x⌋ 表示对 x 向下取整,max(x,y) 表示 x 和 y 中较大的数。如有选手成绩相同,则所有成绩并列的选手都能获奖,因此实际获奖人数可能比计划中多。
第一种方法,用优先队列来模拟过程。
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> q1; //大根堆,选手分数堆
priority_queue<int, vector<int>, greater<int>> q2; //小根堆,计划获奖堆
int main()
{
int n, w, m, s;
bool flag = true;
scanf("%d%d", &n, &w);
for (int i = 1; i <= n; i++)
{
scanf("%d", &s); //当前选手的成绩
m = i * w / 100; //计划获奖人数
if (m < 1)
m = 1;
q1.push(s);
if (q2.size() < m)
{
int t = q1.top();
q1.pop();
q2.push(t);
}
else
{
//q2队列已满
int a1 = q1.top();
int a2 = q2.top();
if (a1 > a2)
{
q1.pop();
q2.pop();
q1.push(a2);
q2.push(a1);
}
}
if (flag)
{
flag = false;
cout << q2.top();
}
else
cout << " " << q2.top();
//cout << "line=" << q2.top() << endl;
}
cout << endl;
return 0;
}这道题你可以用桶的思想,每个分数放到一个桶里。
#include <bits/stdc++.h>
using namespace std;
int t[607];
int main()
{
int n, sum, x, s;
double w;
cin >> n >> w;
for (int i = 1; i <= n; i++)
{
cin >> x;
t[x]++;
sum = 0;
s = i * w / 100 ;
if (s < 1)
s = 1;
for (int j = 600; j >= 0; j--)
{
sum += t[j];
if (sum >= max(1, s))
{
cout << j << " ";
break;
}
}
}
return 0;
}