有n种不同的化学试剂。第i种有ai升。每次实验都要把所有的化学试剂混在一起,但是这些试剂的量一定要相等。所以现在的首要任务是把这些化学试剂的量弄成相等。
有两种操作:
· 把第i种的量翻倍,即第i种的量变成2ai。
· 把第i种的量减半,除的时候向下取整,即把第i种的量变成 ⌊ ai2 ⌋ 。
现在所有的化学试剂的量已知,问最少要变换多少次,这些化学试剂的量才会相等。
样例解释:把8变成4,把2变成4。这样就需要两次就可以了。
Input
单组测试数据。 第一行有一个整数n (1 ≤ n ≤ 10^5),表示化学物品的数量。 第二行有n个以空格分开的整数ai (1 ≤ ai ≤ 10^5),表示第i种化学试剂的量。
Output
输出一个数字,表示最少的变化次数。
Input示例
3 4 8 2
Output示例
2
System Message
(题目提供者)
思路:枚举每个数字,对数字bfs,找出这个数字可以通过+-可以到哪些数字,用个cnt记录 1-100000 这个n个数字能到达几个, 用val记录 这n个数字到 1-100000的总步数, 这一点注意不能每个数都memest book 数组, 用一个 book[i] = id, 而不是简单1就好了
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e5 + 5;
const int INF = 1e9 + 7;
int a[maxn], cnt[maxn], val[maxn], book[maxn];
struct node
{
int x, step;
node(){}
node(int xx, int ss) : x(xx), step(ss) {}
};
void bfs(int x, int id)
{
queue<node> q;
q.push(node(x,0));
book[x] = id;
cnt[x]++;
while(!q.empty())
{
int tem = q.front().x, s = q.front().step;
q.pop();
if(book[tem/2] != id)
{
q.push(node(tem/2, s+1));
book[tem/2] = id;
cnt[tem/2]++;
val[tem/2] += s+1;
}
if(tem*2 <= 1e5 && book[tem*2] != id)
{
q.push(node(tem*2, s+1));
book[tem*2] = id;
cnt[tem*2]++;
val[tem*2] += s+1;
}
}
}
int main()
{
int n;
while(~scanf("%d", &n))
{
memset(book, 0, sizeof(book));
memset(cnt, 0, sizeof(cnt));
memset(val, 0, sizeof(val));
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for(int i = 1; i <= n; i++)
bfs(a[i], i);
int ans = INF;
for(int i = 0; i < maxn; i++)
{
if(cnt[i] == n)
ans = min(ans, val[i]);
}
printf("%d\n", ans);
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int num[200000],book1[200000],book[200000];
int main()
{
int n,x,i;
cin>>n;
memset(book1,-1,sizeof(book1));
memset(book,0,sizeof(book));
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
{
scanf("%d",&x);
int y=x,now=x,nowstep=0,step;
while(y)
{
now=y;
step=nowstep;
while(now<=100000)
{
if(book1[now]==-1)
book1[now]=step;
else
book1[now]=min(book1[now],step);
now*=2;
step++;
}
y>>=1;
nowstep++;
}
book1[0]=nowstep;
y=x,now=x;
while(y)
{
now=y;
while(now<=100000)
{
if(num[now]==i-1)
{
num[now]++;
book[now]+=book1[now];
}
book1[now]=-1;
now*=2;
}
y>>=1;
}
book1[0]=-1;
}
int ans=0x3f3f3f3f;
for(i=0;i<=100000;i++)
{
if(num[i]==n)
{
ans=min(ans,book[i]);
}
}
cout<<ans<<endl;
}