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 }

 

posted @ 2018-09-02 19:36  starry_sky  阅读(317)  评论(0编辑  收藏  举报