2018 牛客多校四 G Maximum Mode (暴力枚举)

题目

题意:给你n个数,然后删除m个数,最后保证众数只有一个且尽量让他打,如果存在输出那个数,不存在输出-1.

思路:就是统计每个数出现的次数,然后按照每个数出现次数从小到大排序,然后暴力枚举每个数为答案时,需要删除几个数,因为从小到大的,我们在枚举这个数为所求答案时,只要减去后缀和即可,然后通过二分枚举第一个出现这个次数的位置,只需这个位置到最后面都减到比枚举这个数出现次数小时就可以了,然后知道到最大值。

代码:(这是队友的代码)

#include<bits/stdc++.h>
using namespace std;
struct node{
    int da;
    int sl;
}p[111111];
int sll[111111];
int hz[111111];
map<int ,int >pp;
bool cp(node x,node y)
{
    if(x.sl!=y.sl)return x.sl<y.sl;
    return x.da<y.da;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        pp.clear();
        int n,m;
        scanf("%d%d",&n,&m);
        int lss;
        int js=1;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&lss);
            if(pp[lss]==0)
            {
                pp[lss]=js;
                p[js].da=lss;
                p[js].sl=1;
                js++;
            }
            else
            {
                p[pp[lss]].sl++;
            }
        }
        sort(p+1,p+js,cp);
        js--;
        for(int i=1;i<=js;i++)
        sll[i]=p[i].sl;
        int ans=-1;
        hz[js]=p[js].sl;
        for(int i=js-1;i>=1;i--)
        hz[i]=hz[i+1]+p[i].sl;
        for(int i=js;i>=1;i--)
        {
            if(p[i].da<ans)
            continue;
            int it=lower_bound(sll+1,sll+js+1,p[i].sl)-sll;
            int sum;
            if(it>i)
            {
                sum=hz[it]-(p[i].sl-1)*(js-it+1);
            }
            else sum=(hz[it]-p[i].sl)-(p[i].sl-1)*(js-it);
            if(sum<=m)
            {
                ans=max(ans,p[i].da);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/imzxww/article/details/81325029