牛客网暑期ACM多校训练营(第四场)G Maximum Mode(思维)

链接:

https://www.nowcoder.com/login?callBack=%2Facm%2Fcontest%2F142%2FG

题意:

给定n个数, 要求删去恰好m个数后的最大总数是多少。

分析:

要使一个数是众数, 只要比他大的数的数量都比自己小就行。

预处理出全部出现次数的最大数(例如, 出现3次最大的是1,出现2次最大的是2等等)。

然后从最大的次数开始枚举, 只关注该次数和比该次数大的数(前缀和),求出每次删的minDel即可。

#include <bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 7;
map<int, int> cnt, Max, t;
int pre[maxN];
int n, m;
int judge(){
    int sum = 0, k = 0, ans = -1;
    for(auto it = Max.rbegin(); it != Max.rend(); it++){
        int a = it -> first, b = it -> second; //a是次数, b是该次数下最大的数
        k += t[a];//k是当前有多少种数
        sum += a * t[a]; //只考虑自己和次数比自己大的数的总数
        int minDel = sum - (a-1) * k - 1;  //要减去的数
        if(minDel <= m){//只要该数小于等于m即可, 剩下的m - minDel随便减
            ans = max(ans, b);
        }
    }
    return ans;
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        cnt.clear();
        Max.clear();
        t.clear();
        scanf("%d %d", &n, &m);
        for(int i = 0; i < n; i++) {
            int num;
            scanf("%d", &num);
            cnt[num]++;
        }
        for(auto it : cnt){
            int a = it.first, b = it.second;
            Max[b] = max(Max[b], a);
            t[b]++;
        }
        printf("%d\n", judge());
    }
}

 

posted @ 2018-08-07 18:27  Neord  阅读(161)  评论(0编辑  收藏  举报