【题解】数组减半
题意
给你一个长度为的数组
。每次可以做一个操作,选择数组中的一个数,对其整除二。求让数组中有
个相同的数的最少操作次数。
题解
由于是肯定可以把数组中变为个相同的数的。我们可以开两个数组,一个数组记录每个数现在有的个数,另一个数组表示获取到下标数这么多的个数需要的操作次数。若某个数的个数大于等于
个了,那么记录下让其有
个的操作次数和原有答案哪个小。剩下的就是暴力了,由于是除二操作,所以每个数的操作次数不超过
次。所以我们对每个数将其依次除二直到一,并把其除二的结果表示的记录个数的数组加一,表示次数的数组加上变为这个数的除二次数。然后对数组
中的每个数遍历一遍就可以了。
复杂度
时间复杂度
代码
#include<bits/stdc++.h> using namespace std; const int N=2e5+5; int a[N],cnt[N],tot[N]; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { scanf("%d",&a[i]); cnt[a[i]]++; } int ans=N; sort(a,a+n); for(int i=0;i<n;i++) { if(cnt[a[i]]>=k) ans=min(ans,tot[a[i]]); else { int res=1,f=a[i]; while(f!=1) { f/=2; cnt[f]++; tot[f]+=res; if(cnt[f]>=k) ans=min(ans,tot[f]); res++; } } } printf("%d\n",ans); return 0; }