UVA 10718 Bit Mask

想了好长时间,实在做不出来了,上网参考了一下大牛的题解。

题目大意:

给定3个数,N,U,L,求在【U,L】 区间内的一个数M ,使得N | M的值最大。

大体思路:

将给定的数N 转化成为2进制

之后从高位向地位一位一位的判断

1、如果这位是0的话,那么要使这一位变成1,既然这样,那么假定这一位变成了1,之后看,这位为1之后的最大最小值是否和给定的区间有交集,如果有的话说明可以变。

2、如果这位是1的话,那么为了使输出结果尽量的小,就要求这一位最好为0,那么就和上面一样,判断,如果这一位是0的话,他的最大最小值是否在区间内,如果在的话就可以取到0,否则的话只能取1了。


总结:感觉是贪心的思路,不过没做出的原因是无法判断变化位数之后,该数是否在区间范围内,还有注意long long 的使用


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXD 100 + 10
#define max(a,b) (a > b ? a : b)
using namespace std;
typedef long long LL;
LL N,M,R,L;
LL b[MAXD];
void biao(){
    b[0] = 1;
    for(int i = 1 ; i <= 32 ; i++)
        b[i] = b[i - 1] * 2;
    return ;
}
int solve(){
    int x[MAXD] = {0};
    int size = 0;
    LL ans = 0;
    while(N){
        x[size++] = N % 2;
        N /= 2;
    }
    for(int i = 31 ; i >= 0 ; i --){
        if(x[i] == 0){
            LL p = ans + b[i];         /*如果这位取1的最小值*/
            LL q = ans + b[i + 1] - 1; /*如果这位取1的最大值*/
            if(p <= R && q >= L)
                ans += b[i];
        }
        else{
            LL p = ans;                /*如果这位取0最小值*/
            LL q = ans + b[i] - 1; /*如果这位取0最大值*/
            if(q < L || p > R) /*如果这个区间不能满足*/
              ans += b[i];
        }
    }
    printf("%lld\n",ans);
}
int main(){
    biao();
    while(scanf("%lld%lld%lld",&N,&L,&R) != EOF){
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值