题目链接:https://codeforces.com/contest/1213/problem/D2
思路:和D1其实差不多,不一样的就是先要预处理每个数变成其他数需要的步数,假设最大值是m,一共最多有有mlogm个数,然后直接从枚举到0 — 2e5看得到相同k个数最少需要几步即可。本来担心是否超时,但是实际上不会,因为在最后的循环里因为f数组里总共最多mlogm个数,加上外层m次循环,最多执行mlogm + m次,不会超时。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int a[maxn];
vector <int> f[maxn];
int main() {
int n , k;
ios::sync_with_stdio(0);
cin >> n >> k;
for(int i = 0 ; i < n ; i++)cin >> a[i];
for(int i = 0 ; i < n ; i++) {
int t = a[i] , cnt = 0;
while(1) {
f[t].push_back(cnt);
t /= 2;
if(!t)break;
cnt++;
}
}
int ans = 0x7f7f7f7f;
for(int i = 0 ; i < maxn ; i++) {
if(f[i].size() >= k) {
sort(f[i].begin() , f[i].end());
int cnt = 0;
for(int j = 0 ; j < k ; j++) {
cnt += f[i][j];
}
ans = min(ans , cnt);
}
}
cout << ans << "\n";
return 0;
}