F. Equalize the Array
Tag:#map #思维
参考:F. Equalize the Array (map、思维)
因为只是用上一次结果的次数和个数,所以不需要每个次数都遍历,即达到了节省时间,提高效率,时间复杂度由O(n^2)降到O(n)。
【供粘贴代码】
#include<iostream>
#include<map>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
map<int,int,greater<int>> map1,map2;
//按从大到小排列的map
int a[n];
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
map1[a[i]]++;
}
for(map<int,int>::iterator it=map1.begin();it!=map1.end();it++){
//first为a[i]数值 second为a[i]的次数
map2[it->second]++;
//x:y
}
int sum=map2.begin()->first*map2.begin()->second;
//从最大次数开始 剩余总数就是其本身个数 x*y
int res=sum;
map<int,int>::iterator prei=map2.begin();
//prei指针记录上一个次数以及个数
for(map<int,int>::iterator i=++map2.begin();i!=map2.end();i++){
//first为次数 second为个数
sum-=(prei->first - i->first)*prei->second;
//前面的先减去
sum+=i->first*i->second;//加上本次数的
i->second += prei->second;
//例:统计总的3次的个数
//为原本四次的减去一次后再加上原本就3次的
prei = i;
//cout<<"sum:"<<sum<<endl;
if(sum > res) res=sum;
}
cout<<n - res<<endl;
}
return 0;
}