题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
有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
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #include <queue> 7 #include <stack> 8 #include <map> 9 #include <set> 10 #include <vector> 11 #include <iostream> 12 using namespace std; 13 #define for0(i, n) for(int i=0; i<(n); ++i) 14 #define for1(i,a,n) for(int i=(a);i<=(n);++i) 15 #define for2(i,a,n) for(int i=(a);i<(n);++i) 16 #define for3(i,a,n) for(int i=(a);i>=(n);--i) 17 #define for4(i,a,n) for(int i=(a);i>(n);--i) 18 #define CC(i,a) memset(i,a,sizeof(i)) 19 #define LL long long 20 #define MOD 1000000007 21 #define INF 0x3f3f3f3f 22 #define MAX 100100 23 24 int dp[MAX]; 25 int num[MAX]; 26 27 void tmp(int x,int y) 28 { 29 for(x*=2,y++; x<MAX; x*=2,y++){ 30 dp[x]++; 31 num[x]+=y; 32 } 33 } 34 35 int main() 36 { 37 int n,m; 38 scanf("%d",&n); 39 memset(dp,0,sizeof(dp)); 40 memset(num,0,sizeof(num)); 41 for(int i=0; i<n; i++){ 42 int path=0; 43 scanf("%d",&m); 44 bool flag=true; 45 while(m){ 46 dp[m]++; 47 num[m]+=path; 48 if(flag) 49 tmp(m,path); 50 if(m&1) 51 flag=true; 52 else 53 flag=false; 54 m/=2; 55 path++; 56 } 57 } 58 int ans=INF; 59 for(int i=0; i<MAX; i++){ 60 if(dp[i]==n) 61 ans=min(ans,num[i]); 62 } 63 printf("%d ",ans); 64 }