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 |
Member of Elite Problemsetters' Panel
題意:給出一個數,和一個範圍,求這個範圍內的一個數使得它與給定的這個數相或最大,注意如果有多個選擇,選取最小的數。
思路:因爲給出的數較大,直接暴力肯定是不行的。
要使得or運算結果最大,我們考慮從最高位開始進行or運算,如果該位是0,我們把他變爲1,並且算出這個時候得M值是否在範圍內,如果在範圍內我們就把它加進來。如果該位是1,要使得M最小,我們儘量讓M的這一位爲0。這個時候會有一個問題,那就是如果M得這一位位0,會不會使得M太小而達不到L到U的範圍,我認爲是不可能的,因爲如果該位選1並且後面所有位數都選1都達不到下線的話,那麼和上一步的選擇就矛盾了。
#include<iostream>
using namespace std;
int ans[64];
long long N,L,U;
long long dex[64];
int main()
{
int i;
dex[0]=1;
for(i=1;i<=32;i++)
dex[i]=dex[i-1]*2;
while(cin>>N>>L>>U)
{
long long x,y,cnt=0;
for(i=0;i<32;i++)
{
ans[i]=N%2;
N/=2;
}
for(i=31;i>=0;i--)
{
if(ans[i]==0)
{
x=cnt+dex[i];
if(x<=U)
cnt=cnt+dex[i];
}
else
{
x=cnt;
y=cnt+dex[i]-1;
if(y<L)
cnt=cnt+dex[i];
}
}
cout<<cnt<<endl;
}
return 0;
}