E 相同的数字
思路:由题意可以发现这个序列可以变成的数字是有一个集合的。
然后那个集合大约10几个元素,他们的共同点时在二进制情况下公共前缀相同,后面加上若干个0.
比如
第一组数据的公共前缀是1,第二组的是11(10进制下的3).
第一组的可变成的解集是(1,2,4,8,…)
第一组的可变成的解集是(3,6,12,24,…) 通项公式 3*2^x
然后就对哪十几个数暴力一下就行了
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+15;
typedef long long ll;
ll a[N],n;
ll change(ll x,ll y)
{
ll cnt=0;
while(y%x!=0)
{
x/=2;
cnt++;
}
while(x!=y)
{
x*=2; cnt++;
}
return cnt;
}
ll solve(ll x)
{
ll ans=0;
for(int i=1;i<=n;i++)
{
ans+=change(a[i],x);
}
return ans;
}
ll check(ll x)
{
ll cnt=0;
for(int i=1;i<=n;i++)
{
ll op=a[i];
while(op>=x)
{
if(op==x)
cnt++;
op/=2;
}
}
if(cnt==n)
return 1;
return 0;
}
int main()
{
ll minz=112345678912345;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
minz=min(minz,a[i]);
}
if(minz==0)
{
ll sb=0;
while(1)
{
sb+=1;
}
}
ll x=1,y;
while(x<=minz*2+1)
{
y=x*2;
if(y>minz)
break;
if(check(y))
{
x=y;
}
else
{
y=x*2+1;
if(y>minz)
break;
if(check(y))
{
x=y;
}
else
{
break;
}
}
}
while(x<=100000000)
x*=2;
ll ans=solve(1);
while(x)
{
ans=min(ans,solve(x));
x/=2;
}
cout<<ans<<endl;
return 0;
}