时间限制:2000ms
单点时限:1000ms
内存限制:256MB
描述
给定两个整数A和B,需要改变几个二进制位才能将A转为B。
输入
1行:A和B,空格隔开
输出
需要改变的位数
样例输入
10 8
样例输出
1
解题思路:
位运算:
A^A=0
A^0=A
判断奇偶性:(x&1==0)?x是偶数:x不是偶数
原因:如果x的二进制最后一位是1那么x一定是奇数
如果x的二进制最后一位是0那么x一定是偶数
1的二进制是0000 0001所以x&1结果要么为0要么为1
获取二进制位是0还是1:
获取x=86的二进制(01010110)的第五位:
①与00010000(第5位为1其余全为0,可以看作1左移4位)相与,然后将结果右移4位,是0则是0,是1则是1
②先将86右移4位,再与1相与,到这一步就相当于判断奇偶性了,是0则是0,是1则是1
不用判断语句,求整数的绝对值:(A^(A>>31))+(A>>>31)
求一个二进制数有多少位为1:
int cnt=0;
while(n!=0)
{
n=((n-1)&n);
cnt++;
}
printf("%d\n",cnt);
给定两个正整数(二进制形式表示)A和B,问把A变为B需要改变多少位(bit)?也就是说,整数A和B的二进制表示中有多少位是不同的?
解法一:举例说明,为了减少复杂度,就使用八位二进制吧。设 A = 0010 1011, B = 0110 0101.
1. C = A & B = 0010 0001;
2. D = A | B = 0110 1111;
3. E = C ^ D = 0100 1110;//异或运算
4. 结果E中有4个1,那么也就是说将A变成B,需要改变4位(bit)。
至于如何判断E的二进制表示中有几个1,可以采用快速移位与方法。
算法原理如下:
1. A & B,得到的结果C中的1的位表明了A和B中相同的位都是1的位;
2. A | B, 得到的结果D中的1的位表明了A和B在该位至少有一个为1的位,包含了A 与 B 都是1的位数,
经过前两步的位运算,,C 中1的位表明了A 和 B在该位都是1,D中为0的位表明了A 和 B 在该位都是0 ,所以进行第三步。
3. C ^ D,E 中为1的位表明了A 和 B不同的位。
AC代码:
#include<stdio.h>
int main()
{
int a,b,c,d,e;
scanf("%d%d",&a,&b);
c=a&b;
d=a|b;
e=c^d;
int cnt=0;
while(e!=0)
{
e=((e-1)&e);
cnt++;
}
printf("%d\n",cnt);
return 0;
}