51nod 1483 化学变化
有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-N中,求出n个数都能转换的数字中,转换次数最少的就行。
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define INF 0x3f3f3f3f 4 using namespace std; 5 const int N = 1e5+10; 6 int a[N*2], c[N*2]; 7 int x, n; 8 int main() { 9 cin >> n; 10 int ans = INF; 11 for(int i = 1; i <= n; i ++) { 12 cin >> x; 13 c[x] ++; 14 int tmp = x, step = 1; 15 while(true) { 16 int y = tmp, cnt = step; 17 while(y*2 < N*2) { 18 a[y*2] += cnt; c[y*2]++; 19 y *= 2; cnt++; 20 } 21 while(tmp%2 == 0) { 22 a[tmp/2] += step; c[tmp/2] ++; 23 tmp /= 2; step++; 24 } 25 if(tmp == 1) break; 26 tmp /= 2; 27 c[tmp]++; 28 a[tmp] += step; 29 step ++; 30 } 31 } 32 for(int i = 1; i < 2*N; i ++) { 33 if(c[i] == n) ans = min(ans, a[i]); 34 } 35 printf("%d\n",ans); 36 return 0; 37 }