牛客网暑期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\n",mx);
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)  fuck();
 return 0;
}

 

posted @ 2018-08-03 02:08  Somnus、M  阅读(226)  评论(0编辑  收藏  举报