題意:給出一個數N,下限L上限U,在[L,U]裡面找一個整數,使得N|M最大,且讓M最小。 很明顯用貪心,用位運算搞了半天,樣例過了後還是WA,沒考慮清楚。。。 然後網上翻到了一個人家位運算一句話解決了 = =....ORZ... 人家的分析:(by天然呆大神) 儘量讓 N 中為 0 的位元,M 為 1;N 為 1 的位元, M 為 0。 因此從高位往低位檢查, 如果 N 為 1(M 儘量為 0),若 M 不能為 0,則必是因為 M 為 1 仍小於 L; 如果 N 為 0(M 儘量為 1),若 M 不能為 1,則必是因為 M 為 0 仍大於 U(此時不可能), 換句話說,M 為 1 時,M 需不大於 U。 注意:如果是long long的位運算操作,最好在數後面加個LL,不如會溢出的。 代碼:
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: uva10718.cpp
* Lauguage: C/C++
* Create Date: 2013-09-04 09:26:39
* Descripton: UVA 10718 Bit Mask, bitmap, greed
*/
#include <cstdio>
#include <cmath>
#define repd(i, a, b) for (int i = (a); i >= (b); i--)
const int MAXN = 100;
int main() {
long long n, l, u, m, t;
while (scanf("%lld%lld%lld", &n, &l, &u) != EOF) {
int len = ceil(log(u) / log(2));
m = 0;
repd(i, len, 1) {
t = m | (1LL << (i - 1)); //1
if (n >> (i - 1) & 1) {
if (t <= l) m = t;
}
else {
if (t <= u) m = t;
}
}
printf("%lld\n", m);
}
return 0;
}