CF-Round 86-div2-D题

CF-Round 86-div2-D题

D. Multiple Testcases

传送门

这道题是一道贪心题~
这道题的题目意思我理解了挺久的,实在是有点纠结。

题目大意:现在让你把一个测试样例数组m[]改成多个测试样例数组。给你一个数组c[]:要求改成的多个测试样例数组中每个数组满足大于等于i的数目不超过c[i];(就是这里我原先理解题目意思就是很迷,就是每个数组都需要满足,我原先是这样理解的,然后看测试样例发现怎么不对劲,然后强行又理解为只要多个测试样例中有一个数组满足就行,后来又发现我搞错了测试样例,到最后发现原来是我先开始理解的题目意思。。。)数组c[]的长度是k,那么保证m[]数组中的数据的大小不会超过k。
问分成的测试样例数组的最小数目是多少。
数目你构造出来的数组

本题思路:我们先来解决最小数目的问题。我们可以把m[]数组先从大到小排序。
我们用ans表示分成的最小数目。
当先操作的假设是i,我们可以获得数组m[]中大于等于i的数目有多少,记录下来。这里就是为什么我们把数组m[]从大到小排序的原因,方便计算(当然,你想从小到大排序也是可以的)
我们用while()直接索引到数组m[]中第一个小于i的位置j(数组m[]是从0开始的),所以我们就可以直接获得到大于等于i的数目就是j。
用**(j + c[i] - 1) / c[i]来表示最少的分组数目。其实用ceil(j / c[i])**就行向上取整。c[i]是要求我们的测试样例中大于等于i的不能超过c[i]个。所以获得最小的分组数目就是看看j包含多少个c[i];多出来的需要再开一个数组放进去。
我们这样下来操作完所有的i,我们只需要维护一个最大的ans就行,满足所有的需求嘛~

我们获得到最小的分组数目ans之后,就是分配的环节。
分配的话我们就是平均分配了,构造出来的每个数组每次分一个,这样循环下来分配即可。就可以得到我们的答案了~

代码部分:

#include <bits/stdc++.h>
using namespace std;

int n, k;

int main()
{
	scanf ("%d%d", &n, &k);
	vector<int> a(n);
	vector<int> c(k + 1);
	for (int i = 0; i < n; i++)
	{
		scanf ("%d", &a[i]);
	}
	for (int i = 0; i < k; i++)
	{
		scanf ("%d", &c[i + 1]);
	}
	sort(a.begin(), a.end(), greater<int>());
	int ans = 0;
	for (int i = k, j = 0; i >= 1; i--)
	{
		while (j < n && a[j] == i)
		{
			j++;
		}
		ans = max(ans, (j + c[i] - 1) / c[i]);
	}
	vector<vector<int> > res(ans);
	for (int i = 0; i < n; i++)
	{
		res[i % ans].push_back(a[i]);
	}
	cout << ans << endl;
	for (int i = 0; i < ans; i++)
	{
		int siz = res[i].size();
		cout << siz;
		for (int j = 0; j < siz; j++)
		{
			cout << " " << res[i][j];
		}
		cout << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值