Question: uva10718-bit mask (Greedy)
Given the 32-bit unsigned integer N, given the boundary L and R, we need to find an integer in the boundary, which is the maximum value obtained by the or operation with N.
Solution: the maximum value required for the OR operation is n to a binary number. To maximize the result, the best solution is [L, r] a certain number of M in it can complement n binary number 01.
Example: 00000111
Then M is better than 11111000.
Of course, this m must meet the requirements in [L, R.
The idea is that M is equal to l first, and L is also converted to the binary number, and then the binary number with N is determined for each bit.
If a certain I bit of N is 0 and the corresponding M bit is 0, you can consider changing this bit of m to 1, however, if M is in the range [L, R], if it is exceeded, another possibility is to save this bit and set the following position to 0, the result of M and N must be larger than the result of the subsequent bits.
If an I-bit on N is 1 and M corresponds to 1, you can consider whether to remove this 1, it is also necessary to ensure that there is a strategy between LR, if it is smaller: in order to make the m value smaller, and the I bit results remain unchanged, you can remove this bit 1 and set all the following bits to 1. In this way, although there may be unnecessary 1, this can be processed later.
A value of 0 and a value of 1 is the best state.
Use long.
Code:
# Include <stdio. h> # include <string. h> const int n = 32; typedef long ll; ll T [N]; bool W1 [N], W2 [N]; // void Init () {T [0] = 1; for (INT I = 0; I <n-1; I ++) T [I + 1] = T [I] * 2;} // split into binary void cut (LL N, bool W []) {for (INT I = n-1; I> = 0; I --) {If (n> = T [I]) {W [I] = 1; n-= T [I] ;}}ll solve (ll l, ll R) {ll ans = L; For (INT I = n-1; I> = 0; I --) {If (! W1 [I] &! W2 [I]) {// All are 0if (ANS + T [I] <= r) ans + = T [I]; else {ll temp = 0; for (Int J = I-1; j> = 0; j --) // calculate the IF (W2 [J]) with the bitwise following 1. temp + = T [J]; If (ANS + T [I]-Temp> = L & Ans + T [I]-Temp <= r) {ans = ans + T [I]-temp; For (Int J = I-1; j> = 0; j --) W2 [J] = 0 ;}}} if (W1 [I] & W2 [I]) {// All 1if (ANS-T [I]> = L) ans-= T [I]; else {ll temp = 0; For (Int J = I-1; j> = 0; j --) // Calculate if (! W2 [J]) temp + = T [J]; If (ANS-T [I] + temp> = L & ANS-T [I] + temp <= r) {ans = ANS-T [I] + temp; For (Int J = I-1; j> = 0; j --) W2 [J] = 1 ;}}}} return ans;} int main () {ll n, l, R; Init (); While (scanf ("% LLD", & N, & L, & R )! = EOF) {memset (W1, 0, sizeof (W1); memset (W2, 0, sizeof (W2); cut (n, W1); cut (L, w2); printf ("% LLD \ n", solve (L, R);} return 0 ;}