题目链接:http://codeforces.com/contest/985/problem/C
很简单的一道题目,但是想了半天还把自己气得要死,因为又读错题意了。。
题意:
给你3个数,n,k,
l
l
,再给你n*k的a[],表示叫你凑n个木桶出来,木桶的长度取决于最小的a,最终的n个木桶最大和最小的差值不超过,问这些木桶长度加起来最长有多少。
那么我们先排个序,如果第n个数和第1个数的差值都大于
l
l
了,那么就是不可能的。之后要分是不是1的情况,为什么要分情况呢?接下来会讲到。
sort完之后我们for一遍看看能与a[1]相距的最大的位置在哪里。记做cnt,那么我们的任务是在这cnt个数里面取出合法且最大的n个数,那么我们先可以得到有cnt-n个数是可以不当做最低点的,那么我们尽量用最小的去和最小的配,为什么?
如果是1 1 2 2 的话,k=2,l=1的时候,当然是11,22是最大的,12,12是最小的,这个想想就知道了。所以有(cnt-n)/(k-1)个数是可以当做被匹配的木板。然后不一定cnt-n个数都能匹配的上,最后可能有剩余,那么就是n-(cnt-n)/(k-1)-1个数了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100005];
int main()
{
int n,k,l,m;
scanf("%d%d%d",&n,&k,&l);
m=n*k;
for(int i=1;i<=m;i++)
scanf("%lld",&a[i]);
sort(a+1,a+1+m);
if(a[n]-a[1]>l)
printf("0\n");
else if(k==1)
{
ll ans=0;
for(int i=1;i<=n;i++)
ans+=a[i];
printf("%lld\n",ans);
}
else
{
int cnt=1;
while(a[cnt]-a[1]<=l&&cnt<=m)
cnt++;
cnt--;
int pos=(cnt-n)/(k-1);
ll ans=0;
for(int i=1,j=1;i<=pos;i++,j+=k)
ans+=a[j];
ans+=a[pos*k+1];
for(int i=1;i<n-pos;i++)
ans+=a[cnt--];
printf("%lld\n",ans);
}
return 0;
}