codeforcesC. Amr and Chemistry

来源:互联网 发布:阿里云自建数据库 编辑:程序博客网 时间:2024/05/22 06:41

C. Amr and Chemistry

Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting experiment.

Amr has n different types of chemicals. Each chemicali has an initial volume ofai liters. For this experiment, Amr has to mix all the chemicals together, but all the chemicals volumes must be equal first. So his task is to make all the chemicals volumes equal.

To do this, Amr can do two different kind of operations.

  • Choose some chemical i and double its current volume so the new volume will be2ai
  • Choose some chemical i and divide its volume by two (integer division) so the new volume will be

Suppose that each chemical is contained in a vessel of infinite volume. Now Amr wonders what is the minimum number of operations required to make all the chemicals volumes equal?

Input

The first line contains one number n (1 ≤ n ≤ 105), the number of chemicals.

The second line contains n space separated integersai (1 ≤ ai ≤ 105), representing the initial volume of thei-th chemical in liters.

Output

Output one integer the minimum number of operations required to make all the chemicals volumes equal.

Sample test(s)
Input
34 8 2
Output
2
Input
33 5 6
Output
5
Note

In the first sample test, the optimal solution is to divide the second chemical volume by two, and multiply the third chemical volume by two to make all the volumes equal4.

In the second sample test, the optimal solution is to divide the first chemical volume by two, and divide the second and the third chemical volumes by two twice to make all the volumes equal1.



看了官方题解才会写。。。

#include<map>#include<vector>#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<set>#define inf 0x3f3f3f3f#define mem(a,x) memset(a,x,sizeof(a))using namespace std;typedef long long ll;typedef pair<int,int> pii;inline int in(){    int res=0;char c;    while((c=getchar())<'0' || c>'9');    while(c>='0' && c<='9')res=res*10+c-'0',c=getchar();    return res;}int vis[100010];int cnt[100010];int step[100010];queue<pii> q;int main(){    int n=in();    for(int i=1;i<=n;i++)    {        int tmp=in();        q.push(pii(tmp,0));//0表示tmp到pii.first的操作步数        while(!q.empty())        {            pii now=q.front();            q.pop();            int x=now.first;            int y=now.second;            if(x>100001)continue;   //上限不超过十万 下限就是0了            if(vis[x]==i)continue; //vis数组标记有没有被访问过            vis[x]=i;               /*vis[x]=i用的很巧妙,i是不断变动的,避免了每次都给vis数组全部初始化,注意i应该从1开始,从0开始会导致标记错乱,因为数组中初始为0*/            cnt[x]++;            step[x]+=y;            q.push(pii(x*2,y+1));   //把x不断乘二入队,有上限限制,复杂度是log的            q.push(pii(x/2,y+1));    //把x不断除二入队,复杂度logx        }    }    int ans=inf;    for(int i=0;i<=100000;i++)    {        if(cnt[i]==n)        {            ans=min(ans,step[i]);        }    }    printf("%d\n",ans);    return 0;}



0 0