位运算

 

位运算

 

功能

示例

位运算

去掉最后一位

(101101->10110)

x >> 1

在最后加一个0

(101101->1011010)

x  << 1

在最后加一个1

(101101->1011011)

x << 1+1

把最后一位变成1

(101100->101101)

x  | 1

把最后一位变成0

(101101->101100)

x | 1-1

最后一位取反

(101101->101100)

x  ^ 1

把右数第k位变成1

(101001->101101,k=3)

x | (1 << (k-1))

把右数第k位变成0

(101101->101001,k=3)

x  & !(1 << (k-1))

右数第k位取反

(101001->101101,k=3)

x ^ (1 << (k-1))

取末三位

(1101101->101)

x  & 7

取末k位

(1101101->1101,k=5)

x & (1<< k -1)

取右数第k位

(1101101->1,k=4)

x  >> (k-1) & 1

把末k位变成1

(101001->101111,k=4)

x | (1 << k-1)

末k位取反

(101001->100110,k=4)

x  ^ (1 << k-1)

把右边连续的1变成0

(100101111->100100000)

x & (x+1)

把右起第一个0变成1

(100101111->100111111)

x  | (x+1)

把右边连续的0变成1

(11011000->11011111)

x | (x-1)

取右边连续的1

(100101111->1111)

(x  ^ (x+1)) >> 1

去掉右起第一个1的左边

(100101000->1000)

x & (x ^ (x-1))

 

 

去掉最后一位          |(101101->10110) |               x >> 1
在最后加一个0        |(101101->1011010) |            x < < 1
在最后加一个1        |(101101->1011011) |            x < < 1+1
把最后一位变成1     |(101100->101101) |              x | 1
把最后一位变成0     |(101101->101100) |              x | 1-1
最后一位取反          |(101101->101100) |             x ^ 1
把右数第k位变成1    | (101001->101101,k=3) |      x | (1 < < (k-1))
把右数第k位变成0    | (101101->101001,k=3) |      x & ~ (1 < < (k-1))
右数第k位取反        | (101001->101101,k=3) |       x ^ (1 < < (k-1))
取末三位               | (1101101->101) |                x & 7
取末k位                | (1101101->1101,k=5) |        x & ((1 < < k)-1)

 

取右数第k位           | (1101101->1,k=4) |             x >> (k-1) & 1
把末k位变成1         | (101001->101111,k=4) |       x | (1 < < k-1)
末k位取反              | (101001->100110,k=4) |      x ^ (1 < < k-1)
把右边连续的1变成0 | (100101111->100100000) |   x & (x+1)
把右起第一个0变成1 | (100101111->100111111) |   x | (x+1)
把右边连续的0变成1 | (11011000->11011111) |      x | (x-1)
取右边连续的1        | (100101111->1111) |           (x ^ (x+1)) >> 1
去掉右起第一个1的左边 | (100101000->1000) |       x & (x ^ (x-1))
判断奇数                   (x&1)==1
判断偶数                    (x&1)==0 
取右边第一个1所在位置  x&-x

 

 

0/1枚举问题 
假设有n个杯子,每个杯子里都装有不同的数量的钱,你可以任意的选择其中的任意数量个杯子带走,请问你有多少种不同收获结果? 
思路 
每一个杯子都有选择或者不选择两种状态,在不考虑复杂度的情况下,可以进行2^n次枚举,获取每一种情况下的结果! 
那么如何实现对2^n中情况下的枚举呢???? 
考虑,对于数 0 ~2^n-1,任意两个不同的数的二进制表示都是不同的,他们每一位的0或1可以表示为该编号的水杯被选择或不被选择,而且要表示2^n-1恰好需要n位!

 

for(int i =0; i<(1<<n); i++) //将1左移n位,其值为2^n 
{
    int cot =0; //初始金钱
    for( int j =0; j<n; j++)
    {
        if(i&(1<<j))   // 在当前的情况下,第j个杯子是否被选中呢?即i的第j位是不是1?
            cot+= val[j];
    }
    cout<< i <<":"<<cot<<endl; //输出第i种情况下的值
}

 

二进制枚举子集

#include<bits/stdc++.h>
using namespace std;
const int N=2010;
int n,m,ans1,ans2,ans3,mp[N][N],u[N],v[N];
int main()
{
    int n;
    cin >> n;
    for(int i=0; i<(1<<n); i++)
    {
        for(int j=0; j<n; j++){
            
            if(i&(1<<j)){
                
                cout << j ;
            }
        }
        cout<<endl;
    }  
    return 0;
}
/*
3 [0 1 2] 
空 
0 /1 /2 
0 1/0 2 
1 2 
0 1 2 
------------------- 
0
1
01
2
02
12
012
*/

 

1.判断一个数字x在二进制下第i位是不是等于1。
方法:if ( ( ( 1 << ( i - 1 ) ) & x ) >0)

解析:将1左移i-1位,相当于制造了一个只有第i位上是1,
其他位上都是0的二进制数,然后用该数与x做与运算,
如果结果>0,说明x第i位上是1,反之则是0。


2.把一个数字x在二进制下的第i位更改成1。

方法:x |= ( 1<<(i-1) )

证明方法与1类似(将1左移i-1位,相当于制造了一个只有第i位上是1,
其他位上都是0的二进制数,然后用该数与x做或运算,只要存在1就为1,
所得结果即为新的x值

当(x&(x<<1))为真
时说明有玉米相邻

 

posted @ 2018-04-10 18:51  Roni_i  阅读(188)  评论(0编辑  收藏  举报