如何快速判断一个数是否为2的倍数?(正整数)
解法一:暴力解法
一个数是否为2的倍数,可分为两者情况1和非1。
1显然是2的倍数,至于其他情况我们仅需暴力模2、处2循环,一旦出现模2结果非0的情况,则表明该数不是2的倍数!
bool func(int x) // x >= 0
{
if (x == 0) return true;
else
{
while (x)
{
if (x % 2) return false;
x /= 2;
}
return true;
}
}
解法二:lowbit(x&-x)
首先,如果一个数是2的倍数,此时该数都对应的二进制只存在唯一 一个1(比如8对应1000)。而 x&-x操作可以从左往右将x中第一个1为界限的值提取出来。比如x为11010100,此时x&-x得到的结果二进制为100。
所以如果一个数为2的倍数,此时x&-x得到的结果任然为x。
if(x - (x & -x) == 0 )
cout << "x是2的倍数" << endl;
解法三:x & (x - 1)
前面以及提到过,如果个数是2的倍数,此时该数的二进制只存在唯一的1,其余全为0。所以如果一个数为2的倍数,此时x & (x - 1)=0!
if(x & (x - 1) == 0 )
cout << "x是2的倍数" << endl;
四、面试题
【题目连接】:数组变换
题目:
牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等。问是否可行。牛牛可以进行的操作是:将数组中的任意一个数改为这个数的两倍。这个操作的使用次数不限,也可以不使用,并且可以对同一个位置使用多次。
解题思路:
我们仅需将数中的最大值作为基准值,只要其他较小的数可以通过多次乘2变为基准值,既符合题意!
此时我们将原问题转化为:基准值能否被其他值整除,并且除数为2的倍数!
#include <iostream>
using namespace std;
int base = 0, N;
int arr[51];
bool func()
{
for(int i = 0; i < N; i++)
{
if(base%arr[i]) return false;
int x = base / arr[i];
if(x&(x - 1))return false;
}
return true;
}
int main()
{
cin >> N;
for(int i = 0; i < N; i++) // 提取最大值,即基准值
{
cin >> arr[i];
base = max(base, arr[i]);
}
// 判断
bool ret = func();
if(ret) cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}