n的二进制表示中,第k位是几
思路
- 先把第k位数字移到最后一位,
n >> k
- 看个位是几,
x & 1
n >> k & 1
即为公式
如何输出10的二进制表示(用我们的位运算实现)
注意这个循环中,并没有改变n的大小
#include <iostream>
using namespace std;
int main(void){
int n = 10;
for(int k = 3; k >= 0; k --) cout << (n >> k & 1);
return 0;
}
lowbit函数实现
实现目标
返回x的最后一位 1
举例:
x的二进制形式: 1010;
lowbit(x) = 2(2 的二进制形式: 10)
x2 的二进制形式: 101000;
lowbit(x) = 8(二进制形式位 1000);
实现原理
核心:x & (- x)
- c++里, 一个整数的负数,表示原数的补码, 补码是由原码(原数的二进制表示)每位取反+ 1 得来的,
上述不免有些许抽象,下面举例说明
原数: 1010....10000
各位取反: 0101....01111
再加一: 0101....10000
x & (x各位取反加一, 即-x) = 10000
一个应用:统计二进制中1的个数
题目链接
题目描述:
给定一个长度为n的数列,请你求出数列中每个数的二进制表示中1的个数。
输入格式
第一行包含整数n。
第二行包含n个整数,表示整个数列。
输出格式
共一行,包含n个整数,其中的第 i 个数表示数列中的第 i 个数的二进制表示中1的个数。
数据范围
1≤n≤100000,
0≤数列中元素的值≤10^9
#include <iostream>
#include <cstdio>
using namespace std;
int lowbit(int x){
return x & -x;
}
int main(void){
int n;
cin >> n;
while(n --){
int x;
cin >> x;
int res = 0;
while(x){
int t = lowbit(x);
x -= t;
res ++;
}
cout << res << ' ';
}
return 0;
}
//在这里,我们举一个数,解释一下这个代码
x = 40(二进制形式: 101000)
lowbit(x) = 8(二进制形式1000)
x -= lowbit(x) = 32;
lowbit(x) = 32(二进制形式: 100000)
x = 0;
一道小题
题目链接
题目描述:
给定一个正整数k,把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是:
1,3,4,9,10,12,13,…
该序列实际上就是:3^0,3^1,3^0+3^1,3^2,3^0+3^2,3^1+3^2,3^0+3^1+3^2,…
请你求出这个序列的第N项的值(用10进制数表示)。
例如,对于k=3,N=100,正确答案应该是981。
在所有的测试数据中,结果均不超过2.1∗10^9)。
分析:
观察可得出规律:
这序列的第N项的值 与 N肯定有关,猜测可能与 N的二进制形式有关。
样例中第四个数, 4 对应的二进制 100, 非0 二进制位对应的 方幂应该为 3 ^ 2 = 9;
样例中第三个数, 3 对应的二进制 11, 非0二进制位对应的 方幂 为: 3^0 + 3 ^ 1 = 4;
把思路转化成代码也非常重要。
代码
#include <iostream>
#include <algorithm>
using namespace std;
int main(void){
int k, n;
cin >> k >> n;
int res = 0, base = 1;
while(n){
res += (n & 1) * base;
base *= k;
n >>= 1;
}
cout << res << endl;
return 0;
}