Educational Codeforces Round 44 (Rated for Div. 2) C.Liebig's Barrels

传送门:点击打开链接

题目大意:

    有n个桶,每个桶需要k个木块,现在给你m(m=n*k)个木块,让你把这些桶塞满。现在,假定一个木桶的容积为这个木桶所插木块中最短的一块,任意两个木桶间的容积差距<=l。

    问如何组装木桶,使总容积最大。

题目思路:

    刚开始看到,哈哈哈,排个序,取前n个木桶就行了呗。。仿佛智障降临,光速wa掉。

    然后开始想,如果出现

                                        3 3 5

                                        1 3 3 6 6 6 6 6 6

这种情况,那么3个桶的容积应该为1,6,6。而不是1,3,3。

    所以换了个wa法。最后看了正解。记大于a[0]+l的第一个值出现的位置为pos。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
typedef long long ll;
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 200005;
ll n,k,l,m,a[maxn],ans,pos;
vector<ll> e;

int main()
{
	cin>>n>>k>>l;
	m = n*k;
	for(int i=0;i<m;i++)
		scanf("%lld",&a[i]);
	sort(a,a+m);
	ll temp = a[0]+l;
	for(int i=0;i<n;i++)
	{
		e.push_back(a[i]);
	}
	if(e[e.size()-1]-e[0]>l)
	{
		cout<<0<<endl;
		return 0;
	}
	e.clear();
	pos = m;
	for(int i=0;i<m;i++)
	{
		if(a[i]>temp)
		{
			pos = i;
			break;
		}
	}
//	cout<<pos<<endl;
	ans = 0;
	int cnt = 0;
	for(int i=0;i<n;i++)
	{
		ans += a[cnt++];
		for(int j=0;j<k-1;j++)
		{
			if(pos-cnt>n-i-1) //pos-cnt表示临界位置与当前位置中间隔了多少个元素,n-i-1表示还剩下多少个木桶
				cnt++; //如果隔的元素数量大于剩余木桶数量的话,说明可以往当前木桶里面继续塞小的,而不是塞较大的
			else
				break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

//3 3 5
//1 3 3 6 6 6 6 6 6




猜你喜欢

转载自blog.csdn.net/zxwsbg/article/details/80420601