洛谷 P7072 [CSP-J2020] 直播获奖(T2)

目录

题目传送门

50分算法

算法

代码

提交结果

AC算法

算法

代码

提交结果

尾声


题目传送门

[CSP-J2020] 直播获奖 - 洛谷https://www.luogu.com.cn/problem/P7072

50分算法

算法

这道题呢,有一种很容易想到的算法,那就是每次输入都排一下序,然后输出第 max(1, p * w%) 名就可以了

可以用 STL 的排序 sort,也可以手写冒泡等排序(如选择、快排等)

这里呢,因为我很懒 sort 更加简洁,所以我用了 sort

注意,sort 需要算法头文件

#include <algorithm>

代码

这个程序很好写,这里就直接给大家贴代码

注意,需要判断 p * w% 是否是 0,如果是,则输出第一名 

#include <iostream>
#include <algorithm>
#define N 100005
using namespace std;

int n, w, a[N];

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

int main() {
	cin >> n >> w;
	for(int p = 1; p <= n; ++p) {
		cin >> a[p];
		sort(a + 1, a + 1 + p, cmp);
		if(p * w / 100 == 0) 
			cout << a[1] << " ";
		else
			cout << a[p * w / 100] << " ";
	}
	
	return 0;
}

提交结果

这可是 CSP-J  2020 年 T2 啊,怎么可能就这么简单呢?

可想而知,这玩意儿时间复杂度 O(n ^ 2 log n),一定 TLE

AC算法

算法

我们观察一下题目数据的值域

注意到“每个选手的成绩均为不超过 600 的非负整数”,这个数还蛮小的嘛,我们貌似可以用桶排把他们都存起来

int a[605];

这里,a[i] 表示成绩为 i 的人有多少个

可以用 m 来表示还需要多少名

从当前最大的成绩开始往前遍历,每次 m -= a[i](即每次还剩的人数减掉本次遍历到的成绩的人数),看什么时候还剩的人数 ≤ 0(即不剩下人了),当前这次遍历到的成绩(i)就是最终的答案

注意,需要判断 p * w% 是否等于 0,如果是,则找第一个(即 m = 1)

for(int p = 1; p <= n; ++p) {
	cin >> x;
	maxx = max(maxx, x);
	++a[x];
	m = p * w / 100;
	if(m == 0)
		m = 1;
	for(int i = maxx; i >= 0; --i) {
		m -= a[i];
		if(m <= 0) {
			cout << i << " ";
			break;
		}
	}
}

代码

最终的 AC 代码:

#include <iostream>
#include <algorithm>
#define N 100005
using namespace std;

int n, w, x, a[N], maxx, m;

int main() {
	cin >> n >> w;
	for(int p = 1; p <= n; ++p) {
		cin >> x;
		maxx = max(maxx, x);
		++a[x];
		m = p * w / 100;
		if(m == 0)
			m = 1;
		for(int i = maxx; i >= 0; --i) {
			m -= a[i];
			if(m <= 0) {
				cout << i << " ";
				break;
			}
		}
	}
	
	return 0;
}

提交结果

我们提交一下~

AC!!! 

尾声

如果这篇题解对您(您的团队)有帮助的话,就帮忙点个赞,加个关注!

最后,祝您(您的团队)在 OI 的路上一路顺风!!!

┬┴┬┴┤・ω・)ノ Bye~Bye~

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值