您的位置:首页 > 其它

Codeforces Round #312 (Div. 2) - C. Amr and Chemistry

2016-07-19 19:06 344 查看
/*
题意: 有 n 种化学药剂,容量分别为 ai ,给出 n 和它们的容量。现有两种操作:
1. 选择一种药剂把它的容量变为 2*ai
2. 选择一种药剂把它的容量变为 ai/2
求最少的操作数使得每种药剂的容量相等。

解题思路:

求出每个数 所有的可以由那两种操作变成的数,用 f 数组记录次数。用 v 数组记录变成这个数用了多少步 。

那么 f 数组里 次数为 n 的数 (即每个数都能够通过变换变成这个数)就是有可能要变成的数。
这里面步数最少的那个就是答案。

由于不相等的数是没办法通过乘 2 变成一样的,所以往上乘的时候到 mx 就可以了。
如果过程中出现了奇数,那么它除 2 再乘 2 之后 又会有新的数所以要单独再往上乘一下,接着再往下除。

*/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 1000005;
int f[maxn],v[maxn],a[maxn];
int main()
{
int n,ans = 1e9,mx=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]); mx = max(mx,a[i]);
}
for(int i=0;i<n;i++)
{
int j = a[i], tmp = 0;
int  stp = 0 ,stp2 = 0;
f[j]++;
while(j < mx)
{
j *= 2; f[j]++;
stp ++; v[j] += stp;
}
j=a[i]; stp = 0;
while( j > 0)
{
if(j&1 && j!=1)
{
j >>= 1; f[j]++ ;
stp ++; v[j] += stp;
stp2 = stp; tmp = j;
while( tmp < mx)
{
tmp = tmp<<1; stp2++;
f[tmp]++; v[tmp] += stp2;
}
}
else
{
j = j>>1; stp++;
f[j]++; v[j] += stp;
}
}
}
for(int i=1;i<mx*2;i++)
{
if(f[i]==n) ans = min(ans,v[i]);
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: