51nod 1483 化学变换(思维)
2018-02-16 23:09
357 查看
Description
有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
解题思路
列举每一个数可能产生的所有数,然后标记每一个数产生的次数和步数,当产生次数为n 时即代表每个数都可以变换成这个然后选取最小值.对于偶数而言,直接乘2到最大值,除2到最小值;
但对于奇数而言,要记得除2之后再乘2会得到新的数值.
代码实现
#include<bits/stdc++.h> #define IO ios::sync_with_stdio(false);\ cin.tie(0);\ cout.tie(0); typedef long long ll; using namespace std; const int maxn=1e5+7; #define INF 0x3f3f3f3f int a[maxn],mark[maxn*2],num[maxn*2]; void solve(int t) { int step=0,temp=t; while(temp<maxn) { mark[temp]+=1; num[temp]+=(step++); temp*=2; } step=0,temp=t; while(temp) { if(temp%2==0||temp==1) { temp/=2; mark[temp]+=1; num[temp]+=(++step); } else { temp/=2; mark[temp]+=1; num[temp]+=(++step); int ne=temp,nes=step; while(ne<maxn) { ne*=2; mark[ne]+=1; num[ne]+=(++nes); } } } } int main() { IO; int n; cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; solve(a[i]); } int ans=INF; for(int i=0;i<maxn*2;i++) { if(mark[i]==n) ans=min(ans,num[i]); } cout<<ans<<endl; return 0; }
相关文章推荐
- 51Nod 1483 化学变换(思维+暴力)
- 51nod--1483--化学变换(思维)
- 51nod 1483 化学变换【思维】
- 51Nod 1483 化学变换
- 51nod 1483 化学变换
- 51nod 1483 化学变换(暴力,预处理)
- 51nod 1483 化学变换 | 二进制 暴力
- CodeForces 558 C. Amr and Chemistry && 51NOD 1483 化学变换(暴力 + 贪心)
- 51Nod 1483 化学变换
- Codeforce 558C. Amr and Chemistry &51nod 1483 化学变换 By Assassin 暴力大法好
- 51nod 1483 化学变换
- 51nod 1483 化学变换 (枚举+bfs or 枚举+技巧)
- 51NOD-1483 化学变换(贪心)
- 1483 化学变换 (思维)
- 51NOD 1483 化学变换
- 51Node 1483----化学变换(暴力枚举)
- nod-1483-化学变换
- 1483 化学变换 乱搞题
- 1483 化学变换(暴力)
- 51nod1483-技巧&标记&思维-化学变换