N多校2018d4t7Maximum Mode

多动手写思路才能让思维更加清晰吖~~~

例2 2 3 3 4 

首先用map记录每个数出现次数mp[2]=mp[3]=2 , mp[4]=1;

然后t【】记录每个次数的个数;

然后从大到小扫描频率,记录如果答案是某频率,至少去掉多少点(这里要去掉的最少点<=m没关系,如果m>min的话,去掉除该值的其他数就可以了)

然后扫描各个值,得到最大值

ac代码:

#include <bits/stdc++.h>
using namespace std;
#define per(i,a,b) for(int i=a;i<=b;i++)
const int inf =0x3f3f3f;
#define siz 200005
int n,m,a[siz],t[siz],ans[siz];
map<int,int>mp;
void init()
{
    mp.clear();
    memset(t,0,sizeof(t));
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        init();
        per(i,1,n){
            scanf("%d",&a[i]);
            mp[a[i]]++;
        }
        for(auto it:mp){
            t[it.second]++;
        }
        int s=0,del=0;//s表示当前ti是要去的,del表示ti前 至少 要去掉的!
        for(int i=n;i>=1;i--){
            del+=s;//如t1到t4(ti表示i频率的有几种数)是1 2 0 4 则考虑4时去一次t4-1==3
            if(t[i]==0)continue;    //,考虑3时去一次(t4-1)+t4(因为频率是4的要去掉两次才比3小)
            s+=t[i];
            int tmp=del+s-1;
            ans[i]=tmp;
        }
        int mm=0;
        for(auto it:mp){
            if(ans[it.second]<=m)mm=max(mm,it.first);
        }
        if(mm==0)printf("-1
");
        else printf("%d
",mm);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/WindFreedom/p/9383610.html