题目链接:http://codeforces.com/contest/1213/problem/D1
大致题意:
给出一个数组arr,可以将数组里的数进行向下取整的除2操作,求最少的操作数使得数组中有k个数相同
#include <bits/stdc++.h>
const int maxn=1e5+10;
using namespace std;
int a[maxn];
int num[maxn];
int sum[maxn];
int main()
{
ios::sync_with_stdio(0);
int n,m;
int ans=maxn;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
int temp=0;
int x=a[i];
while(x){
num[x]++;
sum[x]+=temp;
if(num[x]==m)
ans=min(ans,sum[x]);
temp++;
x/=2;
}
}
cout<<ans<<endl;
return 0;
}
另附困难版本代码,n,k范围变大
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <numeric>
#include <math.h>
typedef long long ll;
using namespace std;
const int N = 2e5+11;
int n,k;
vector<int>a[N];
int main(){
scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i++){
int x,k = 0;
scanf("%d",&x);
while(x){
a[x].push_back(k);
x /= 2;
k++;
}
}
int ans = 1e9;
for(int i = 1;i <= 200*1000;i++){
if(a[i].size() >= k){
sort(a[i].begin(),a[i].end());
ans = min(ans,accumulate(a[i].begin(),a[i].begin()+k,0));
}
}
printf("%d
",ans);
return 0;
}