【Atcoder Beginner Contest 100】C- *3 or /2

【Atcoder Beginner Contest 100】 C - *3 or /2

Time Limit: \(2\) sec / Memory Limit: \(976\) MB

Score: \(300\) points

Problem Statement

As AtCoder Beginner Contest \(100\) is taking place, the office of AtCoder, Inc. is decorated with a sequence of length \(N\), \(a={a_1,a_2,a_3,...,a_N}\).
Snuke, an employee, would like to play with this sequence. Specifically, he would like to repeat the following operation as many times as possible:

For every \(i\) satisfying \(1≤i≤N\), perform one of the following: "divide \(a_i\) by \(2\)" and "multiply \(a_i\) by \(3\)".
Here, choosing "multiply \(a_i\) by \(3\)" for every \(i\) is not allowed, and the value of \(a_i\) after the operation must be an integer.

At most how many operations can be performed?

Constraints

\(N\) is an integer between \(1\) and \(10 000\) (inclusive).

\(a_i\) is an integer between \(1\) and \(1 000 000 000\) (inclusive).

Input

Input is given from Standard Input in the following format:

\(N\)
\(a_1\) \(a_2\) \(a_3\) \(......\) \(a_N\)

Output

Print the maximum number of operations that Snuke can perform.

/*
这道题很简单,让你选择最大的操作次数把所有数变成奇数
我们通过观察可以发现,操作次数只由含多少个2确定
比如:4 一共操作两次 “/2”(1当然也是奇数了)
所以我们只要找出所有数含了多少个2,输出个数即可

这里我们不用while循环做,用新函数 ——bulitin_ctz()取每个数最末后的0的个数
例如:4 二进制为0100 后面一共2个0,每次除2都要向右移动一位去掉一个0,一共操作两次
再比如:5 二进制位0101 后面一共0个0,即操作0次
代码如下
*/
#include <iostream>
int N,a,i=0,ans=0;
int main(){
std::cin>>N;
while(i<N)
{
	std::cin>>a;
	ans+=__builtin_ctz(a);
	i++;
}
std::cout<<ans<<'\n';
return 0;
}
/*
注:
高效位运算函数:
 __builtin_ffs (unsigned int x)
返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4。
 __builtin_clz (unsigned int x)
返回前导的0的个数。
 __builtin_ctz (unsigned int x)
返回后面的0个个数,和__builtin_clz相对。
 __builtin_popcount (unsigned int x)
返回二进制表示中1的个数。
 __builtin_parity (unsigned int x)
返回x的奇偶校验位,也就是x的1的个数模2的结果。

此外,这些函数都有相应的usigned long和usigned long long版本,只需要在函数名后面加上l或ll就可以了,比如 __builtin_clzll。(否则均默认int)
*/
posted @ 2021-08-17 02:33  Black-OR-White  阅读(78)  评论(0)    收藏  举报