hdu 3711 Binary Number 位运算(^ 与&)的应用

两个数A和B异或的结果C就是他们二进制中相同的为0不同的为1,所以本题就是要数C的二进制中1的个数,而求一个数二进制中1的个数的方法很多,下面简单介绍几种:

1.数C对2取余,判断余数是不是为1,若是记录一次,之后数C除以2,再进行前面的描述,知道数C为0,结束,代码如下:

int getBits(int n) {
	int res;
	res = 0;
	while (n) {
		if (n % 2 == 1) {
			res++;
		}
		n /= 2;
	}
	return res;
}

2.同上,不过对2取余,采用&,除以2,采用右移,代码如下:

int getBits(int n) {
	int res;
	res = 0;
	while (n) {
		if (n & 2 == 1) {
			res++;
		}
		n >>= 2;
	}
	return res;
}

3.如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减去1,那么原来处在整数最右边的1就会变成0,原来在1后面的所有的0都会变成1。其余的所有位将不受到影响。举个例子:一个二进制数1100,从右边数起的第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成1,而前面的1保持不变,因此得到结果是1011

我们发现减1的结果是把从最右边一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000。也就是说,把一个整数减去1,再和

int getBits(int n) {
	int res;
	res = 0;
	while (n) {
		res++;
		n = n & (n - 1);
	}
	return res;
}

PS:n&(n-1)==0;//二进制数只有一位位1,则该数是2的整数次幂.

 

/*
* hdu3711.c
*
* Created on: 2011-8-27
* Author: 王竹
*/

#include
<stdio.h>
#include
<stdlib.h>
#define nmax 101
#define INF 0x7fffffff
int numa[nmax], numb[nmax];
int cmp(const void *a, const void *b) {
return *(int *) a - *(int *) b;
}
int getNum0(int n) {
int res;
res
= 0;
while (n) {
res
++;
n
= n & (n - 1);
}
return res;
}

void solve(int m, int n) {
int i, j, k, te, temp, nmin;
for (i = 0; i < n; i++) {
nmin
= INF, k = -1;
for (j = 0; j < m; j++) {
te
= numb[i] ^ numa[j];
temp
= getNum0(te);
if (nmin > temp) {
nmin
= temp;
k
= j;
}
}
printf(
"%d\n", numa[k]);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen(
"in.data", "r", stdin);
#endif
int T, i, m, n;
while (scanf("%d", &T) != EOF) {
while (T--) {
scanf(
"%d %d", &m, &n);
for (i = 0; i < m; i++) {
scanf(
"%d", numa + i);
}
for (i = 0; i < n; i++) {
scanf(
"%d", numb + i);
}
qsort(numa, m,
sizeof(numa[0]), cmp);
solve(m, n);
}
}
return 0;
}

转载于:https://www.cnblogs.com/xiaoxian1369/archive/2011/08/27/2155752.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值