uva 10718 Bit Mask (位运算)

uva 10718 Bit Mask

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

100 50 50

100 0 100

1 0 100

15 1 15


59

50

27

100

1

题目大意:每组数据包含三个有效数据:1)N; 2)L ; 3)U   要在L~U之间找出M和N做或运算得出的值最大的,并且本身值最小的数。

解题思路:一开始,直接用或运算+暴力,毫不犹豫的超时了。然后用了另一种方法,先将N转化为二进制存在一个数组中,然后从高位开始往下遍历,构造M,若当前位为0,则在不超过上限的情况下,M的该位为1;若当前位为1,则在达不到下限的情况下,将M的该位赋为1。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#define M 32
typedef long long ll;
using namespace std;
ll N, L, U, B[M + 1];
int A[M + 1];
int change(int *T, ll a) {
	for (int i = 0; i < M; i++) {
		T[i] = a % 2;
		a /= 2;
	}
}
int main() {
	B[0] = 1;
	for (int i = 1; i < M; i++) {
		B[i] = B[i - 1] * 2;
	}
	while (scanf("%lld %lld %lld", &N, &L, &U) == 3) {
		ll ans = 0, temp;
		change(A, N);
		for (int i = M - 1; i >= 0; i--) {
			if (!A[i]) {
				temp = ans + B[i];
				if (temp <= U) { //当N的该位为0,则在不超过上限的情况下,选1
					ans += B[i];
				}
			}
			else {
				temp = ans + B[i] - 1;
				if (temp < L) { //如果该位选1,达不到下限,则选1,若可以达到下限,为了保持ans最小,就选0
					ans += B[i];
				}
			}
		}
		printf("%lld\n", ans);
	}
	return 0;
}
时间: 2024-11-07 21:27:49

uva 10718 Bit Mask (位运算)的相关文章

uva 10718 Bit Mask(位操作贪心)

这道题目我没怎么想就去看题解了,原因只是因为我觉得我想不出来,真没有自信啊...唉,真没有钻入题目进去的 恒心...慢慢培养,不能再这样了,不能轻易看题解啊... 分析: 首先题目中已经说了枚举肯定会超时的,所以呢,网上看到的是枚举32比特位,然后和n与,来判断当前位是1还是0, 如果是0的话,就换成1,除非换成1后比区间的最大值还要大.因为换成一能保证最后或的结果最大. 如果是1的话,就换成0(这样能保证结果相同的情况下选的数最小)除非换成0后它的最大值比区间最小值还要小,就 是说当前位后面所

UVA 10718 Bit Mask

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define sc3(x,y,z) scanf("%lld%lld%lld", &x, &y, &z) 6 #define pf(x) printf("%lld\n",x) 7 #define FOR(i,b,e) fo

【UVA】658 - It&#39;s not a Bug, it&#39;s a Feature!(隐式图 + 位运算)

这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 << pos)); 将s中二进制第k位变成1的处理方式: s = s | (1 << pos); 2.二进制运算: [1] & : 1 & 1 = 1 , 1 & 0 = 0 , 0 & 0 = 0; 快速判断奇偶性: if(a & 1);//为奇数

UVa 818Cutting Chains (暴力dfs+位运算+二进制法)

题意:有 n 个圆环,其中有一些已经扣在一起了,现在要打开尽量少的环,使所有的环可以组成一条链. 析:刚开始看的时候,确实是不会啊....现在有点思路,但是还是差一点,方法也不够好,最后还是参考了网上的题解,大神们的代码就是不一样, 但还是看了好久才看懂.首先是用二进制法进行暴力,因为 n 最大才是15,不会超时的,然后就是在暴力时判断打开这些环时,剩下的是不是还存在环, 如果存在那么不是不行的,然后再判断是不是有的环有两个分支以上,因为一个环如果成链那么最多只有两个分支,所以多于两个的也是不对

位运算常用操作总结位运算应用口诀清零取反要用与,某位置一可用或若要取反和交换,轻轻松松用异或移位运

来源:http://www.educity.cn/wenda/381487.html 位运算常用操作总结位运算应用口诀 清零取反要用与,某位置一可用或 若要取反和交换,轻轻松松用异或 移位运算 要点 1 它们都是双目运算符,两个运算分量都是整形,结果也是整形.     2 " $amp;     3 "$amp;>amp;>quot;$右移:右边的位被挤掉.对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统.     4 "

Java位运算在程序设计中的使用:位掩码(BitMask)

在Java中,位运算符有很多,例如与(&).非(~).或(|).异或(^).移位(<<和>>)等.这些运算符在日常编码中很少会用到. 在下面的一个例子中,会用到位掩码(BitMask),其中包含大量的位运算.不只是在Java中,其他编写语言中也是可以使用的. 例如,在一个系统中,用户一般有查询(Select).新增(Insert).修改(Update).删除(Selete)四种权限,四种权限有多种组合方式,也就是有16中不同的权限状态(2的4次方). 一般情况下会想到用四个

位运算(&amp;amp;、|、^)与逻辑运算(&amp;amp;&amp;amp;、 ||)差别

刚无意在一篇文章中看到了位运算(&.|)和逻辑运算(&&.||)的介绍.想起了自己薄弱的基础知识.于是百度了几把总结了下. 首先从概念上区分下,位运算是将运算符两边的数字换算成二进制(例:0000010001)后比較同样位置上的0.1进行运算的.逻辑运算即比較运算符两边的逻辑值(true或false).概念比較抽象.下边借助实际样例比較下. 位运算 先将每一个数转换成二进制.然后进行.位或(|)表示相相应的每位至少有一个为1.则结果为1,仅仅有两个都为0.结果才为0.位与(&

位运算之——按位与(&amp;)操作——(快速取模算法)

由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快. 按位与(Bitwise AND),运算符号为& a&b 的操作的结果:a.b中对应位同时为1,则对应结果位也为1. 例如: 10010001101000101011001111000 & 111111100000000 --------------------------------------------- 10101100000000 对10101100000000进行右移8位得到的是101011,这就得

位运算心得

1.位运算 今天复习位运算的时候发现一个规律,之前都没有注意的,就是二进制和2的关系 2^0 = 0000 2^1 = 0010 2^2 = 0100 2^3 = 1000 后面的一次类推,可以很容易识别一个二进制的数和2的关系 二进制之间的运算也都可以换算成和2相关的运算,和2相关的乘法和除法直接可以转化成移位运算来解决 例如: 0010 + 0010 => 0010 * 2 => 0010 左移1位 => 0100 = > 2*2 = 4 0101 * 0100 = >