牛客多校第四场 G Maximum Mode
题意:给出一个n个数的序列,我们可以删除m个数,然后我们要求出现次数最多并且最大的,
分析:普遍的暴力的遍历肯定是TLE的,我们可以小贪心下,用map记录次数,然后排序以次数大的优先,相等值大的优先,为什么这样呢?我们可以知道我们取得是众数,优先次数多的话,可以保证结果肯定是成立的,就是不知道是不是最大的,所以我们要依此遍历下去,这里有个神奇的sum,sum表示的是前面出现过的总次数,为什么神奇呢?首先看下一个结论 假设以这个规则得出三个数:数值->(次数) 3->(4) ,
2->(3) . 4->(2) ,假设现在定位到最后一个,我们要开始判断了,那我们怎样才可以取第三个呢?很简单只要 4-2+3-2<=m 即可,假设次数a1,a2,a3. 那么就是a1-ai+a2-ai+....+ai-1-ai<=m ,换下顺序sum-i*(a[i]-1)<=m;
#include<bits/stdc++.h> using namespace std; #define ll long long struct no { ll x,y; no(){}; no(ll a,ll b){x=a; y=b;}; }a[100010]; bool cmp(no x,no y) { if(x.y==y.y) return x.x<y.x; return x.y>y.y; } int main() { int t,n,m; scanf("%d",&t); map<ll,ll>mp; map<ll,ll>::iterator it; while(t--) { mp.clear(); ll x; scanf("%d%d",&n,&m); for(int i=0 ; i<n ; i++) { scanf("%lld",&x); mp[x]++; } int cnt = 0; for(it = mp.begin() ; it!=mp.end() ; it++) { a[cnt].x = it->first ; a[cnt].y = it->second ; cnt++; } sort(a,a+cnt,cmp); ll sum = 0; ll fa=0,num=0;///fa判断是否为第一位,num存答案 for(int i=0 ; i<cnt ; i++) { if(i<cnt-1 && a[i].y == a[i+1].y)///判断次数是否相等,相等的时候取最大那个 { sum += a[i].y; continue; } else { ///是第一个的话,直接取; if(fa==0) { if(sum-i*(a[i].y-1)<=m)///判断次数是否可以删除那么多 { fa=1; num=a[i].x; } } else { if(a[i].x>num)///先判断是否大于,在判断是否够删除 { if(sum-i*(a[i].y-1)<=m) { fa=1; num=a[i].x; } } } sum+=a[i].y; } } if(fa==0) printf("-1\n"); else printf("%lld\n",num); } }