原题
这道题因为
a
i
,
k
,
n
a_i,k,n
ai,k,n都比较小,对数据进行一些预处理就可以解决。
1
≤
a
i
≤
2
×
1
0
5
1
≤
k
≤
n
1\le a_i \le 2\times 10^5\\ 1\le k\le n
1≤ai≤2×1051≤k≤n
解题步骤
1.定义矩阵
c
h
u
[
i
]
[
j
]
chu[i][j]
chu[i][j],表示
a
i
a_i
ai,除以2,连除
j
j
j次后的结果
O
(
n
)
\mathcal{O}(n)
O(n)
2.定义数组
c
i
s
h
u
[
p
]
cishu[p]
cishu[p],记录
p
=
c
h
u
[
i
]
[
j
]
,
c
i
s
h
u
[
p
]
p=chu[i][j],cishu[p]
p=chu[i][j],cishu[p]表示
p
p
p在
c
h
u
chu
chu矩阵中出现的次数。
O
(
n
)
\mathcal{O}(n)
O(n)
3.对于
c
i
s
h
u
[
p
]
≥
k
cishu[p]\ge k
cishu[p]≥k,得到p需要的最少操作次数,在所有值中再取最小值。
O
(
n
2
)
\mathcal{O}(n^2)
O(n2)
这道题n并不大,所以时间上不会超限,分析一下空间上也不会超限
代码实现
#include<bits/stdc++.h>
using namespace std;
#define MAX 55
#define MAXAI 200004
#define MI 24
int a[MAX];
int chu[MAX][MI]; //除
int cishu[MAXAI];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
int j=0;
chu[i][0]=a[i];
cishu[a[i]]++;
while(chu[i][j]!=0){
int tmp=chu[i][j]/2;
chu[i][j+1]=tmp;
cishu[tmp]++;
j++;
}
}
int Min=INT_MAX;
for(int i=0;i<MAXAI;i++){
if(cishu[i]>=k){
int ci=0;
int num=0;
for(int p=0;p<MI;p++){
for(int j=0;j<n;j++){
if(chu[j][p]==i){
if(p==0||p!=0&&chu[j][p-1]!=0)
ci++; //避免重复计算chu[i][j]矩阵之后未使用的部分都是0
num+=p;
if(ci==k){
if(Min>num){
Min=num;
}
break;
}
}
}
}
}
}
printf("%d\n",Min);
return 0;
}