首页 > 代码库 > uva10718 - Bit Mask(贪心)

uva10718 - Bit Mask(贪心)

题目:uva10718 - Bit Mask(贪心)


题目大意:给出32位无符号的整数n ,给定边界L和R,要求在这个边界里面找出一个整数,它和N做或运算得到的值最大。


解题思路:要求做或运算得到的值最大,先N化成2进制的数,然后要使得结果最大的话,最好的就是【L,R】里面的某个数M能和N二进制数01互补.

例如: 00000111

          那么M最好就是 11111000

          当然这个M需要满足【L,R】内。

          思路是M先先等于L,将L也转换成二进制数,然后和N的二进制,每一位都进行判断。

          如果N的某i位上面是0,而M上对应的位也是0,那么可以考虑将M上的这一位变成1,但是的判断是否M在【L,R】区间内,如果超过了,那么还有一种可能就是为了保全这个位而将后面的位置为0,这样的M与N的结果肯定必保留后面的位的结果要大。  

         如果N上的某i位是1,而M上对应的也是1,那么根据题意要最小的M,这里就可以考虑是否能去掉这个1,同样也是要保证在LR之间,如果较小了,也还是有一种策略:为了使得M的值更小,并且i位的结果仍然不变,可以将这一位1去掉,而将后面的所有的位全置为1。这样虽然后面可能有不需要的1,但是这个可以后面处理。

          一个0一个1就是最好的状态了,不用处理。

         要用 long long 。


代码:

#include <stdio.h>
#include <string.h>

const int N = 32;
typedef long 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;	
}
//拆分成二进制数
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]) {  //都是 0

			if (ans + t[i] <= r)
				ans += t[i];
			else {            
				
				ll temp = 0;
				for (int j = i - 1; j >= 0; j--)   //计算后面的位是1的
					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] = 0;
				}
			}
		}

		if (w1[i] && w2[i]) {  //都是1

			if (ans - t[i] >= l)
				ans -= t[i];
			else {
			
				ll temp = 0;
				for (int j = i - 1; j >= 0; j--)    //计算后面位是0的
					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%lld%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;
}