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

题意:一共T组样例,对于每组样例给出一行N和M,分别表示随后一行有N个数和需要删去的数的数量为M.且要求删除M个数后该数列中的众数唯一且最大,否则输出-1.

#include <bits/stdc++.h>
#define MAXN 100010
using namespace std;
int n,m,a[MAXN],t[MAXN],ans[MAXN];
map<int,int> mp;

void fuck()
{
    int i;
    mp.clear();
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        mp[a[i]]++;
        t[i]=0;///存储mp中it->second数组相同的个数
    }
    for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
        t[it->second]++;
    }
    int s=0,del=0;
    for(i=n;i>=1;i--){
        del+=s;///使当前数成为众数需要删除的次数
        if(t[i]==0) continue;
        s+=t[i];//
        int res=del+s-1;///这个公式推了一遍发现实在写得太好了!!!
        ///ans[3]=t[3]-1
        ///ans[2]=(t[3]+t[2])+(t[3])-1
        ///ans[1]=(t[3]+t[2]+t[1])+(t[3]+t[2])-1
        ///就相当于要找一个众数为2的数的话,对3个数的话肯定要减去两个t[3]达到条件
        ///而减去一个一是为了防止加上t[2]==1的情况

        ans[i]=res;///选有i个相同数时删除的个数。
        ///如4333221一串数,t[1]=2;t[2]=1;t[3]=1;
        ///经过循环得ans[1]=6,ans[2]=2;ans[3]=0
        ///即选mp==3的数时不需要删除任何数
    }
    int mx=-1;
    for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
        if(ans[it->second]<=m) mx=max(mx,it->first);
    }
    printf("%d
",mx);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)  fuck();
 return 0;
}
原文地址:https://www.cnblogs.com/Fy1999/p/9411144.html