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 |
59 |
很容易想到要用貪心,但是真的貪起來還挺麻煩的,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;
}