CF389C Fox and Box Accumulation

\(\texttt{Codeforces}\) 题面

不知道为什么洛谷上没有这道题。。。

题目大意

给出 \(n\) 个数,分别为 \(a_1,a_2,\cdots,a_n\)

\(a_i\) 表示第 \(i\) 个箱子上最多能 \(a_i\) 个箱子。

叠是指这样:

形如上图这样的我们称为一堆。

求最少需要多少堆把所有箱子都叠起来。

题目分析

考虑贪心。

我们可以先将 \(a\) 数组升序排列。

对于每个数,我们依次遍历所有数,如果有一个箱子能够叠在当前这一堆的最下面(即 \(a_i\) 大于当前这一堆箱子数量),那么立刻处理,并且删除掉这个数。

答案就是能够进行多少次这个操作。

我们如果使用数组的话,非常不方便完成删除操作,所以可以使用 \(\rm STL\) 里的 multiset

代码

//2021/11/17

//2021/11/18 

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>

#include <cstdio>

#include <climits>//need "INT_MAX","INT_MIN"

#include <set>

#define enter() putchar(10)

#define debug(c,que) cerr<<#c<<" = "<<c<<que

#define cek(c) puts(c)

#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;

#define speed_up() std::ios::sync_with_stdio(false)

namespace Newstd
{
	inline int read()
	{
		char c;
		bool flag=false;
		while((c=getchar())<'0' || c>'9')
		{
		    if(c=='-') flag=true;
		}
		int res=c-'0';
		while((c=getchar())>='0' && c<='9')
		{
		    res=(res<<3)+(res<<1)+c-'0';
		}
		return flag?-res:res;
	}
	inline void print(int x)
	{
		if(x<0)
		{
			putchar('-');x=-x;
		}
		if(x>9)
		{
			print(x/10);
		}
		putchar(x%10+'0');
	}
}

using namespace Newstd;

using namespace std;

int n;

multiset<int>st; 

int main(void)
{
	n=read();
	
	for(register int i=1;i<=n;i++)
	{
		int x=read();
		
		st.insert(x);
	}
	
	int ans(0);
	
	while(!st.empty())
	{
		int cnt(0);
		
		multiset<int>::iterator it=st.begin();
		
		while(it!=st.end())
		{
			if((*it)>=cnt)
			{
				cnt++;
				
				st.erase(it++);
			}
			
			else
			{
				it++;
			}
		}
		
		ans++;
	}
	
	printf("%d\n",ans);
	
	return 0;
}
posted @ 2021-11-18 13:26  Coros_Trusds  阅读(38)  评论(0编辑  收藏  举报