程序竞赛——位运算常用操作
位运算
&
与
|
或
~
非
^
异或
>>
右移
<<
左移
常用操作:
(1) 求x的第k位数字 x >> k & 1
(2) lowbit(x) = x & -x
,返回x的最后一位1
求整数的二进制数表示中的第k位是几?
n = 15 =(1111)2 :从0位开始的(右到左)
- 先把第k位移到最后一位 n >> k (将第k位移到了个位上)
- 看个位是几 x&1
总结:1、2汇总: n >> k & 1
int n = 10;// 1010
for(int k = 3;k >= 0; k--)// 4位数的二进制数
cout<< (n >> k & 1); // 1010
lowbit(x):返回x的最后一位1
lowbit()函数用来取一个二进制最低位的1与后边的0组成的数。
应用:统计x中1的个数(每次把最后一个1去掉)
x = 1010 lowbit(x) = 10
x= 101000 lowbit(x) = 1000
实现原理:x & -x
= x & (~x + 1)
,负数的补码:原码取反加一。利用了负整数的补码特性
【例题】acwing801. 二进制中1的个数
【方法一】传统思路:先将十进制数转为二进制数,然后统计出现1的个数(遍历判断)
#include<iostream>
using namespace std;
const int N = 100000+10;
int q[N];
// 将十进制数转为二进制数并统计1的个数
int count(int n)
{ int k = 0, ans = 0;
while(n != 0)
{
q[k++] = n % 2;
n = n / 2;
}
for(k--; k >= 0; k--)
{
if(q[k] == 1)
ans++;
}
return ans;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
cout<<count(x)<<" ";
}
return 0;
}
【方法二】位运算
#include<iostream>
using namespace std;
int lowbit(int x)
{
return x & (-x);
}
int main(){
int n;
cin>>n;
while(n--)
{
int x;
int res = 0;
cin>>x;
while(x)
{
x -= lowbit(x); // 减去每一次的最后一位1
res++;
}
cout<<res<<" ";
}
return 0;
}
总结:
求n的第k位数字: n >> k & 1
。
返回n的最后一位1:lowbit(x) = x & -x
。应用:求某一个数的二进制有多少位1。
注:如果文章有任何错误或不足,请各位大佬尽情指出,评论留言留下您宝贵的建议!如果这篇文章对你有些许帮助,希望可爱亲切的您点个赞推荐一手,非常感谢啦