Amr and Chemistry CodeForces 558C(BFS)

时间:2023-03-09 16:44:47
Amr and Chemistry CodeForces 558C(BFS)

http://codeforces.com/problemset/problem/558/C

分析:将每一个数在给定范围内(10^5)可变成的数(*2或者/2)都按照广搜的方式生成访问一遍,标记*问的步数,之后遍历区间找到被访问次数达到n(所有数都可以变成这个数)并且标记的需要步数最少即可。

注意:当是奇数的时候,例如11(11/2=5 5*2=10),按照这么算(除2后再乘2)回重新得到一个新的数

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include<vector>
#include<queue>
#include<algorithm> using namespace std;
typedef long long LL; const int maxn=;
const int INF=0x3f3f3f3f;
const int mod=;
int time[maxn], step[maxn]; void UP(int x, int steps)///统计x的偶数倍
{
while(x<=)
{
time[x]++;
step[x]+=steps;
x*=;
steps++;
}
} void BFS(int x)
{
UP(x, ); int steps = ;
while(x)
{
steps++; if(x& && x>)///统计x是奇数的情况,并且x!=1
{
x/=;
UP(x, steps);
}
else///统计x是偶数的情况
{
x/=;
time[x]++;
step[x]+=steps;
}
}
} int main()
{
int n, num; while(scanf("%d", &n)!=EOF)
{
memset(time, , sizeof(time));///标记这个数被生成了几次
memset(step, , sizeof(step));///标记生成这个数的步数 for(int i=; i<=n; i++)
{
scanf("%d", &num); BFS(num);
} int ans = INF;
for(int i=; i<=; i++)
{
if(time[i] == n)///若这N个数都被标记成了i,取相对应的步数值
ans = min(ans, step[i]);
} printf("%d\n", ans);
}
return ;
} /*
2
1 1
*/