[CSP-J2020 T2] 直播获奖

作者: qiqi 分类: CSP-J 发布时间: 2025-10-06 12:17

查看题目

题目描述: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;
}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

标签云