UVA10718 - Bit Mask

看到这个题我们简单的思路就是从L到R逐个数的暴力,

但是人家有明显提示了,所以我们要另寻妙法了

要求从某个范围里找到M,使得M|N最大,如果有多个M满足最大的话就输出最小的,

考虑第一个条件,找到M使得M|N最大,那么我们应该从二进制方向出发,使得M|N最大,

则我们从最高位到最低位比较,如果N对应的数是0的话,在其他条件合适的话肯定让M对应的该位数为1。

如果N对应的数是1的话,则此时我们为了满足第二个条件,应当使得M的该数位上的数为0,

但是我们还要考虑范围因素,每次都得判断M|N是否在范围内,如果超过了,则就舍弃该数位等于1的机会,如果还不足L,则及时加上,即让该数位等与1

#include <cstdio>
int main ()
{
    int maxbit;
    unsigned n, l, r, tt, ans;
    while(scanf("%u%u%u",&n,&l,&r)!=EOF)
    {
        maxbit = 0; tt = r;
        while(tt) {maxbit++; tt/=2;} maxbit-=1;
        tt = 0; ans = 0;
        for(int i = maxbit; i >= 0; i--)
        if(tt = ans+(1<<i), (tt<=r&&(n&1<<i)==0)||(ans<l&&(l&1<<i)))   ans=tt;
        printf("%u\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值