位图法

注明: 左移n位就是乘以2的n次方,右移n位就是除以2的n次方
 解析本例中的void set(int i) {        a[i>>SHIFT] |=  (1<<(i & MASK)); }
 1)  i>>SHIFT:
 其中SHIFT=5,即i右移5为,2^5=32,相当于i/32,即求出十进制i对应在数组a中的下标。比如i=20,通过i>>SHIFT=20>>5=0 可求得i=20的下标为0;
 
 2)  i & MASK:
 其中MASK=0X1F,十六进制转化为十进制为31,二进制为0001 1111,i&(0001 1111)相当于保留i的后5位。
 
 比如i=23,二进制为:0001 0111,那么
 0001 0111
 &    0001 1111 = 0001 0111 十进制为:23
 比如i=83,二进制为:0000 0000 0101 0011,那么
 0000 0000 0101 0011
 &   0000 0000 0001 0000 = 0000 0000 0001 0011 十进制为:19
 
 i & MASK相当于i%32。
 
 3) 1<<(i & MASK)
 相当于把1左移 (i & MASK)位。
 比如(i & MASK)=20,那么i<<20就相当于:
 0000 0000 0000 0000 0000 0000 0000 0001 << 20
 =0000 0000 0001 0000 0000 0000 0000 0000
 
 
 注意上面 “|=”.
 

 */

#include <iostream>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000

int a[1 + N/BITSPERWORD];//申请内存的大小


//set 设置所在的bit位为1
void set(int i) {
    a[i>>SHIFT] |=  (1<<(i & MASK));
}
//clr 初始化所有的bit位为0
void clr(int i) {
    a[i>>SHIFT] &= ~(1<<(i & MASK));
}
//test 测试所在的bit为是否为1
int  test(int i){
    return a[i>>SHIFT] &   (1<<(i & MASK));
}

int main()
{   int i;
    for (i = 0; i < N; i++)
        clr(i);
    while (scanf("%d", &i) != EOF)
        set(i);
    for (i = 0; i < N; i++)
        if (test(i))
            printf("%d\n", i);
    return 0;
}

此文章转自 快课网
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值