https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1483
这道题看题解了,完全没有思路。。。。
数据范围1e5,所以就把所有当前容量的倍数做了标记,
对于小于他的数,如果结果是奇数,那么也把奇数的倍数做标记(可以证明他和原数的倍数永远不会重叠。),这点不容易想到。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+300;
int num[maxn];
int ste[maxn];
int n;
void sol(int u){
int s=u;
int temp=0;
while(s<maxn){
num[s]+=temp;
ste[s]++;
s*=2;
temp++;
}
int s2=u;
temp=0;
while(s2>1){
if(s2%2==1&&s2!=1){
int tem=temp+2;
int s3=s2/2;
s3*=2;
while(s3<maxn){
num[s3]+=tem;
ste[s3]++;
s3*=2;
tem++;
}
}
int t=s2/2;
temp++;
num[t]+=temp;
ste[t]++;
s2/=2;
}
}
int main()
{ int n,a;
while(~scanf("%d",&n)){
memset(ste,0,sizeof(ste));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++){
scanf("%d",&a);
sol(a);
}
int ans=1e7;
for(int i=0;i<maxn;i++){
if(ste[i]==n){
ans=min(ans,num[i]);
}
}
printf("%d\n",ans);
}
return 0;
}