给出n个数, 你可以对任意一个数进行数次 除以 2 的操作直到为0, 给出一个整数m, 求 要使 n 个数中 有 m 个数相同, 至少操作几次。
好暴力,, 枚举出n个数中每个数除以2直到为0的所有数, 找出一个数 t 使n个数中的m个数变为t所需操作数最少。
最大值为 2*1e5 所以开一个这么大的vector就够了.
然后为了得到 某个 数 n 变为 t 所需的最少操作步骤,我们需要从小到大依次枚举, 这样 t 第一次出现时,一定是 n 变为 t 所需的最少操作数, 因为数组经过排序后是递增的。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector <int> A[2*100005];
int main(){
int n, s;
cin>>n>>s;
int arr[2*100005];
for(int i = 0; i < n; i++){
cin>>arr[i];
}
sort(arr,arr+n);
for(int i = 0; i < n; i++){
int t = arr[i];
int step = 0;
A[t].push_back(step++);
while(t){
t>>=1;
A[t].push_back(step++); // 因为数组排序后是上升的的,所以t第一次出现的步数就是最小步数,
}
}
int Min = 9999999;
for(int i = 0; i <= 2*100000; i++){
if(A[i].size() < s) continue; // A[i].size 代表的是 i 出现了几次。 每一个A[i][j] 是得到 i 需要的最小步数
int ans = 0;
for(int j = 0; j < s ; j++){ // 取 最小的 s 个
ans += A[i][j];
if(ans > Min) break;
}
if(Min > ans) Min = ans;
}
cout<<Min<<endl;
return 0;
}