计蒜客 单独的数字 位运算总结

a>>j&1 把a转化成二进制之后第j个位置的值

>>运算是整体右移动

&1运算取出二进制的最后一位

所以a>>j&1  如果我们要取数,要用&1取,但是&1是取最后一位,我们需要移动a,把想要去的第j位移动到最后一位。也就是右移j位。


通着这个操作统计每一个数字的每一个位置的总值。

最后都%3,因为如果a数字出现三次,每个位置都对应出现了三次,%3后是归零的。只会剩下那个单独一个的



最后我们要把sum变成十进制。

我们知道对于010101

十进制 = 0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 + 0*2^4 + 1*2^5

             =sum[i]*2^i + ....

<<运算,就是当前树乘以2的几次房。

所以就是sum[i]<<i;




//补充知识

&运算

0 & 0=0
0 & 1=0
1 & 0=0
1 & 1=1
可用来用于判断奇偶和取最后一位数
因为&1,如果最后一位是0,则为0.如果最后一位是1,则为1
一般就是&1,不会&其他的
 
 
|运算
0 & 0=0
0 & 1=1
1 & 0=0
1 & 1=1
直接|1,可以让最后一位强行变成1
 

这一个操作可以让当前数字变成最接近他的偶数

 ^ 运算

0 & 0=0
0 & 1=1
1 & 0=1
1 & 1=0
就是让一个数完全变成相反的
可以不利用其他变量进行交换a^=b^=a^=b;(可以不借助别的变量)
检查两个数是否相等a^b=0,则相等
一个数如果同时^两次,那么不变
例题:
如果m个数,其中只有一个数出现了奇数次,就那么数
不停的异或即可,最终值就是那个奇数

 
<< 运算

左移运算,乘以2的几次方

常用于把二进制转化成十进制

十进制 = 0*2^0 + 1*2^1 + 0*2^2 + 1*2^3 + 0*2^4 + 1*2^5

             =sum[i]*2^i + ....

<<运算,就是当前树乘以2的几次房。

所以就是sum[i]<<i;



 >> 运算

右移运算符。

有些操作我们只能对最后一位处理,我们需要这样移动过去进行处理




对于某些问题,比如什么一个数出现了几次啦,关于数字的操作问题的题目,可以思考一下是否能用到位运算



#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int sum[32],n,a;
int main()
{
   memset(sum,0,sizeof(sum));
   cin>>n;
   for(int i=0; i<n; i++)
    {
        cin>>a;
        for(int j=0; j<32; j++)
        {
            sum[j]+=a>>j&1; //a>>j&1 的意思是a转化为二进制后第j个位置的值   
            sum[j]%=3;     //我们统计所有数字j位置的综合。 之后%3,因为出现三次,%3就归零了
        }                    //只会剩下那个出现一次的,要不是1,要不是0.而j从0-32表示的就是最后那个单独的数
    }
    int ans = 0;
    for(int i=0; i<32; i++)
    {
        ans += sum[i]<<i;  //把二进制数转化成十进制
    }
    cout<<ans<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值