ybt1674堆蛋糕
1674:堆蛋糕
时间限制: 1000 ms 内存限制: 262144 KB
【题目描述】
其实moreD是一个十分犀利的蛋糕师。他最喜欢的食物就是蛋糕。
一天,他自己做出了\(n\)个圆柱状的蛋糕,每个蛋糕都有一个底面圆的半径\(R_i\)。高度都是一样的。
moreD在开始享用他的蛋糕大餐之前忽然觉得,圆柱状的蛋糕没有什么诱惑力。moreD看到了别人结婚用的蛋糕都是很多很多层的,那样的蛋糕才比较给力。但是堆太多层的蛋糕比较困难,于是moreD想要堆出许多三层的蛋糕,再开始自己的蛋糕大餐。
当然,作为蛋糕师,moreD在堆蛋糕的时候不会对蛋糕的形状有任何破坏,而且,moreD希望三层蛋糕的半径从上往下严格递增。这才是一个普通的好蛋糕。
moreD在考虑一个十分重要的问题,最多可以堆出多少三层蛋糕呢?
【输入】
第一行仅包含一个整数\(n\),表示蛋糕的数量。
接下来\(n\)个整数,表示每个蛋糕半径的大小\(R_i\)。
【输出】
输出一行仅包含一个整数,表示最多可以做成多少个蛋糕。
【输入样例】
6
1 2 3 4 3 2
【输出样例】
2
【输入样例2】
6
1 1 1 2 2 3
【输出样例2】
1
【数据规模及约定】
对于20%的数据:\(n≤10\)。
对于40%的数据:\(n≤2000\)。
对于60%的数据:\(n≤100,000\)。
对于100%的数据:\(n≤3,000,000,R_i≤n\)。
贪心算法!
先用桶排,找出各个型号蛋糕出现的个数。由于没有重复,所以选个数多的三种组成三层蛋糕,以此法循环,直到不满三种。
我是从小的开始先,所以只过两个点!
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e6+10;
int n,ans,mx;
int tj[maxn];
priority_queue<int>q;
int min(int a,int b,int c)
{
if(a>b)a=b;
if(a>c)a=c;
return a;
}
int js;
int main()
{
scanf("%d",&n);
for(int x,i=1;i<=n;++i)
{
scanf("%d",&x);
tj[x]++;
mx=max(mx,x);
}
for(int i=1;i<=mx;++i)
if(tj[i])
q.push(tj[i]);
while(q.size()>=3)
{
int a=q.top();q.pop();
int b=q.top();q.pop();
int c=q.top();q.pop();
ans++;
if(a>1)q.push(a-1);
if(b>1)q.push(b-1);
if(c>1)q.push(c-1);
}
cout<<ans<<endl;
return 0;
}