ACWing——145周赛题解

文章讨论了如何在编程中处理平均成绩计算、套餐设计中的二分策略以及分班问题的优化算法,强调了浮点数类型的重要性,并提供了C++代码示例来解决这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:

&1:平均成绩

&2:套餐设计

&3:分班

例1:平均成绩

例1:平均成绩

思路:……水题。But 注意用浮点数类型    否则除法损失精度

代码:
 

#include<iostream>
using namespace std;

int main()//acw-145-a
{
	float a,b,c;
	cin>>a>>b>>c;
	if(((a+b+c)/3)>60) cout<<"YES";
	else cout<<"NO";
	return 0;
}

例2:套餐设计

例2:套餐设计

思路:不知道大家写这题是什么感受,我是觉得这题就差把二分答案糊题上了(捂脸)

我们先对题目分析一波:

ai表示种类i从0到100的个数与题目所给不一样

因为c/c++整型除法是向下取整的

又因为t是固定的

所有对每个样例有上图所给公式

因为ai和n都是固定的,我们只需要二分枚举答案即可也即二分答案

题目所求是最大,最大?->右逼近

不懂的小伙伴可以看看这篇文章(狗头)

所以有代码:

#include<iostream>
using namespace std;

int a[105];
int main()//145-b
{
	int n, m, i, x, sum;
	cin >> n >> m;
	for (i = 0; i < m; i++)
	{
		cin >> x;
		a[x]++;
	}
	int l = 0, r = m / n, mid;
	while (l < r)
	{
		mid = (l + r + 1) >> 1, sum = 0;
		for (i = 0; i < 105; i++) sum += a[i] / mid;
		if (sum >= n) l = mid;
		else r = mid - 1;
	}
	cout << l;
	return 0;
}

例3:分班

例3:分班

思路:因为任意两个班的讲课速度都不能超过l

所以我们只需要通过确定    学习能力最差的学生  到  学习能力为最差生+l  间的学生个数cnt即可判定是否有答案

根据题目要求为了使讲课速度最大,然而又因为  任意两个班的讲课速度都不能超过l

所以我们要在这cnt个学生里,尽可能挑选学习能力相对强的作为“班底”

我们可以先对这cnt个学生的学习能力排序

然后再这cnt个学生里把学习能力相对差的塞到一起(被塞的学生打0,相当于去除,这个时候fcnt--),满k后再开新班(即下图1到图2的过程)

这是这一过程的代码解释:

while (fcnt > n)
{
	while (com < k)
	{
		b[i] = 0, fcnt--;
		if (fcnt == n) break;
		com++, i++;
	}
	com = 1, i++;
}

当fcnt==n时就是答案

至于  学习能力大于l  的人不用管,不论怎么塞都不影响结果

代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;

ll sum, cnt,a[100005], b[100005], fmin=2e9;
int main()//145-c
{
	int n, m, k, l, i;
	cin >> n >> k >> l;
	m = n * k;
	for (i = 0; i < m; i++)
	{
		cin >> a[i];
		fmin = min(fmin, a[i]);
	}
	for (i = 0; i < m; i++)
	{
		if (a[i] <= (fmin + l))
		{
			b[cnt] = a[i];
			cnt++;
		}
	}
	if (cnt < n) cout << "0";
	else
	{
		sort(b,b+cnt);
		ll com = 1, i = 1, fcnt = cnt;
		while (fcnt > n)
		{
			while (com < k)
			{
				b[i] = 0, fcnt--;
				if (fcnt == n) break;
				com++, i++;
			}
			com = 1, i++;
		}
		for (i = 0; i < cnt; i++) sum += b[i];
		cout << sum;
	}
	return 0;
}

ps:

一开始我是用vector写的,但是tle了

while (b.size() > n)
{
	while (com < k)
	{
		b.erase(b.begin() + i);
		if (b.size() == n) break;
		com++;
	}
	com = 1, i++;
}

原因是erase的时间复杂度是o(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值