Link
Http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_ problem&problem=1659
"Original question"
In bit-wise expression, mask is a common term. You can get a certain bit-pattern using mask. For example, if your want to make the a 32-bit number zero, can use 0XFFFFFFF0 as mask and perform a bit-wi SE and operation. Here's have to find such a bit-mask.
Consider you are given a 32-bit unsigned integer N. You are have to find a mask M such this l≤m≤u and N OR M is maximum. For example, if N is and L = then M'll be and N OR m'll be maximum. 127 which. 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, and 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 could not end within the time limit.
Sample input:
100 50 60
100 50 50
100 0 100
1 0 100
15 1 15
Sample output:
59
50
27
100
1
"The main effect of the topic"
Give three 32-bit unsignedint digital n,l,u, find a number M, L≤m≤u, make n | The result of M (or) is the largest and the M is the smallest.
"Analysis and Summary"
Since L and U can be very different, such as l=1,u=2137384647, the direct violence enumeration will certainly time out. So need to change a method, with greedy thinking.
In order to make n| M Max, so that the binary high of this result is as much as 1, so you can use arrays to simulate binary computations. The initial value of this binary array is equal to L.
And then enumerate from high to low,
For the K-bit, if the n[k]==0, so in order to make the value of N as large as possible, it is necessary to make n[k] into 1, in order to make n[k] into 1, we must let m[k]=1 (so that n[k]| M[k]==1), but also consider m[k] after the change to 1, the new value of M is >u, if more than U can not let m[k into 1.
This column more highlights: http://www.bianceng.cn/Programming/sjjg/
If N[K] is already equal to 1, then there is no need for m[k to be 1 (because of 1|0==1). So m[k] If it's 0, regardless of the continuation of the enumeration, if M[k] is 1, try whether to change M[k] to 0, if it becomes 0 and then satisfy the value of M binary array >=l, it can become 0 (because it makes m as small as possible).
The resulting m array represents the value of the answer.
Code
* * * uva:10718-bit Mask * type:greedy * result:accept * time:0.012s * author:d_double * * * * * #inclu
de<iostream> #include <cstdio> #include <cstring> using namespace std;
Long Long n,l,u;
BOOL Bit[32], tmp[32];
Inline long Long getValue () {Long long ans=0, u=1;
for (int i=31; i>=0;-i) if (Bit[i]) {ans = u<< (31-i);
return ans;
Long long Solve () {memset (bit, 0, sizeof (bit));
for (int i=0; i<32; ++i) Bit[i] = l>> (31-i) &1; for (int i=31; i>=0;-i) {if ((N >> I & 1) ==0 && bit[31-i]==false) {bit[31-i]=
True
memcpy (TMP, bit, sizeof (bit));
int j=31-i+1;
BOOL Flag=false;
while (j<=32) {if (GetValue () <=u) {flag=true; } while (bit[j]==falsE && j<32) ++j;
if (j==32) break;
BIT[J] = false;
} if (!flag) {memcpy (bit, TMP, sizeof (TMP));
Bit[31-i] = false;
} else if ((n>>i&1) ==1&&bit[31-i]==true) {Bit[31-i] = false;
if (GetValue () < L) Bit[31-i] = true;
} return GetValue ();
int main () {while (scanf ("%lld%lld%lld", &n,&l,&u)!=eof) {Long long ans=solve ();
printf ("%lld\n", ans);
return 0; }