coderforce Educational Codeforces Round 44 (Rated for Div. 2) C(赛后补题)

C. Liebig's Barrels
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You have m = n·k wooden staves. The i-th stave has length ai. You have to assemble n barrels consisting of k staves each, you can use any k staves to construct a barrel. Each stave must belong to exactly one barrel.

Let volume vj of barrel j be equal to the length of the minimal stave in it.

You want to assemble exactly n barrels with the maximal total sum of volumes. But you have to make them equal enough, so a difference between volumes of any pair of the resulting barrels must not exceed l, i.e. |vx - vy| ≤ l for any 1 ≤ x ≤ n and 1 ≤ y ≤ n.

Print maximal total sum of volumes of equal enough barrels or 0 if it's impossible to satisfy the condition above.

Input

The first line contains three space-separated integers n, k and l (1 ≤ n, k ≤ 105, 1 ≤ n·k ≤ 105, 0 ≤ l ≤ 109).

The second line contains m = n·k space-separated integers a1, a2, ..., am (1 ≤ ai ≤ 109) — lengths of staves.

Output

Print single integer — maximal total sum of the volumes of barrels or 0 if it's impossible to construct exactly n barrels satisfying the condition |vx - vy| ≤ l for any 1 ≤ x ≤ n and 1 ≤ y ≤ n.

Examples
Input
Copy
4 2 1
2 2 1 2 3 2 2 3
Output
Copy
7
Input
Copy
2 1 0
10 10
Output
Copy
20
Input
Copy
1 2 1
5 2
Output
Copy
2
Input
Copy
3 2 1
1 2 3 4 5 6
Output
Copy
0

Note

In the first example you can form the following barrels: [1, 2], [2, 2], [2, 3], [2, 3].

In the second example you can form the following barrels: [10], [10].

In the third example you can form the following barrels: [2, 5].

In the fourth example difference between volumes of barrels in any partition is at least 2 so it is impossible to make barrels equal enough.


这道题忍住了看题解。自己独立思考了QAQ。

但是div2的C题还是属于那种自己可以做但需要花很长时间的那种,希望慢慢进步(D题先凑合着题解自己写QAQ)
补完了这道题去洗澡澡

题意很简单,给n,k,l, l是体积限定的条件见上,k是每个小序列的长度,n是小序列的个数。再给你N*K个数
这道题是一道贪心的题目,我的想法是对于这一系列数字来说:对于分成的k个序列,每个序列中最小的就是代表这个体积,在符合情况| Vi-Vj |<=l的情况下取尽可能大的体积。

首先对数组排序,首先排序后的arr[1]肯定是一个序列的体积(放哪里都是最小的),那么我要满足l的限定条件的话,体积的取值一定在arr[1]~arr[1]+l中,找到arr[1]+l这个值所对应的数组下标。

对于一般情况,n<arr[1]+l,取贪心的状况:我要使得体积取值总和尽可能地大,就是对于每个体积(我们从小到大来取)尽可能多得涵盖掉较小的数,我们举一个例子:1、2、3、4、5、6、7假设能取最小体积的范围为这个,我们总共需要两个序列,每个序列5个数,那么对于1我就把序列的5个数涵盖掉2、3、4、5,这样就能尽可能地大了。
然后只需要考虑每个序列最小体积地取值,剩余地自然会从剩下的值中取。

再考虑涵盖不掉全部的情况,比如刚才的例子,对于刚刚的6来说,只剩下6和7了,自然涵盖完,但是如果n是3呢,就只能一个取6 一个取7,单独判断一下就好(k不行变成k-1一直减到0为止(保证k过后剩下的元素个数大于等于还没取得序列个数))
说了一大堆,上代码(懒得加注释了改了好多遍才过之前一直WA7是用样例推得时候最小为1,就一直l+1到好久....)

菜啊qwq

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long LL;
LL arr[100010];
LL tem[100010];


int main()
{
	LL sum=0;
	LL n,k;
	LL l;
	cin>>n>>k>>l;
	for(LL i=1;i<=n*k;i++)
	{
		cin>>arr[i];
	}
	sort(arr+1,arr+1+n*k);
	LL j=0;
	tem[++j]=1;
	int ans;
	for(LL i=1;i<=n*k;i++)
	{
		if(arr[i+1]!=arr[i])
		tem[++j]=i;
		else tem[j]=i;
		if(arr[i]==l+arr[1])
		ans=i;
		else if(arr[i]<l+arr[1]&&l+arr[1]<arr[i+1])
		ans=i;
	}
	LL pre=1;
	if(ans<n)
	{
		cout<<"0";
		return 0;
	}
	if(n==1)
	{
		cout<<arr[1];
		return 0;
	}
	for(LL m=1;m<=n;m++)
	{
          if(pre+k-1+(n-m)<=ans&&k!=0)
          {
          	sum+=arr[pre];
          	pre=pre+k;
		  }
		  else
		  {
			while(--k)
			{
				if(pre+k-1+(n-m)==ans)
				{
					sum+=arr[pre];
					pre=pre+k;
					k=0;
					break;
				}
			}
		  }
        if(k==0)
        {
        	for(LL i=pre;i<=ans;i++)
        	{
	        	sum+=arr[i];
	        }
	        break;
        }
	}
	   cout<<sum;
	   return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值