前往:我自己搭建的博客
题目
CF1393C Pinkie Pie Eats Patty-cakes
题解
题目即求任意两个相同数的距离的最小值的最大值,可以二分答案。在判断距离>=d是否可行时,用贪心思想:依次填写数列中的数,每次填写时,填重复次数最多的且符合条件的数。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n;
int cnt[maxn],tmp[maxn],c[maxn];
//c[i]表示数字i出现的次数,cnt[]用来复制c[],意义相同,tmp[]是填写的数列
priority_queue<pair<int,int> > q;
inline bool can(int d)
{
for(int i=1;i<=n;i++) cnt[i]=c[i];
for(int i=1;i<=n;i++) if(cnt[i]) q.push(make_pair(cnt[i],i));
for(int i=1;i<=n;i++)
{
if(i-d-1>=1&&cnt[tmp[i-d-1]]) q.push(make_pair(cnt[tmp[i-d-1]],tmp[i-d-1]));
if(q.empty()) return 0;
tmp[i]=q.top().second,cnt[tmp[i]]--,q.pop();
}
return 1;
}
inline int erfen()
{
int l=0,r=n;
while(l<r)
{
int mid=(l+r+1)>>1;
can(mid) ? l=mid : r=mid-1;
}
return l;
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d",&n); memset(c,0,sizeof(c)); //初始化
for(int i=1;i<=n;i++) {int x; scanf("%d",&x); c[x]++;}
printf("%d\n",erfen());
}
return 0;
}