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/p/2155752.html