uva 10718 - Bit Mask

Problem A

Bit Mask

Time Limit

1 Second

In bit-wise expression, mask is a common term. You can get a certain bit-pattern using mask. For example, if you want to make first 4 bits of a 32-bit number zero, you can use 0xFFFFFFF0 as mask and perform a bit-wise AND operation. Here you have to find such a bit-mask.

Consider you are given a 32-bit unsigned integer N. You have to find a mask M such that L ≤ M ≤ U and N OR M is maximum. For example, if N is 100 and L = 50, U = 60 then M will be 59 and N OR M will be 127 which is maximum. If several value of M satisfies the same criteria then you have to print the minimum value of M.

Input
Each input starts with 3 unsigned integers N, L, U where L ≤ U. Input is terminated by EOF.

Output
For each input, print in a line the minimum value of M, which makes N OR M maximum.

Look, a brute force solution may not end within the time limit.

Sample Input

Output for Sample Input

100 50 60
100 50 50
100 0 100
1 0 100
15 1 15

59
50
27
100
1

 

很容易想到要用贪心,但是真的贪起来还挺麻烦的,n or m要最大, m在[L,U]内,m要尽可能小,

先考虑n>m的情况,要or运算最大,自然把n转化为二进制后,出现零的位置,尽量由m转化为二进制来填补;

所以可以从最高位开始,遇到n的二进制位为0的,判断m在该位为1是否会大于U,但是最后虽然可以使n or m最大,m却可能小于L,这样贪心只保证了m<=U;

因为我们忽略了m的二进制位为0的情况;

有个常识需要注意A=1000....(n个0)B=11111(n个1) A=B+1 A>B ;所以为了避免m小于L的情况出现,我们只需要判断,m二进制位后面全取1是否小于L,是的话,当前位必须取1;

最后整理一下思路就是,初始化m的所有二进制位为0,我们从高位到低位找到哪些些位置尽量为1(n or m 大),那些位置位置必须为1(m>=L),

#include <stdio.h>
#include <string.h>
int main()
{ 
 long long ans,i,j,m,n,l,u,a[100],b[100],exp[100],size=32;
 exp[1]=1;
 for (i=2;i<=size;i++)
 exp[i]=exp[i-1]*2;
 while (scanf("%lld%lld%lld",&n,&l,&u)!=EOF)
 {  
  memset(a,0,sizeof(a));
  memset(b,0,sizeof(b));
  i=0;
  while (n)
  {
   a[++i]=n%2; 
   n=n/2;
  }

  for (i=size;i>=1;i--)
  {
   if (a[i]==0)
   { 
    b[i]=1;
    m=0;
    for (j=1;j<=size;j++)
    m=m+b[j]*exp[j];
    if (m>u) b[i]=0;
   }
   if (b[i]==0)
   {
    m=0;
	for (j=32;j>i;j--)
    m=m+b[j]*exp[j];
	if (m+exp[i]-1<l) b[i]=1; 
   }
  }
 ans=0;
 for (i=1;i<=32;i++)
 ans=ans+b[i]*exp[i];
 printf("%lld\n",ans);
 }
 return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值