ICS Return 1 when x contains an odd number of 1s,0 otherwise(判断二进制表示中1的个数是否为奇数)

本题棘手的地方在于不能用循环语句,并且最多只能包含12个算术运算、位运算和逻辑运算。


思路找了非常久,用了从一般到特殊,才慢慢发现规律。


首先来看只用两个bit的情况,未知数x共有四种(00,01,10,11),若要判断1的个数奇偶,不难发现只需用最高位异或最低位就可实现,即 x^(x>>1),如果结果为1,那么有奇数个,否则有偶数个。


从中不难看出对于32位的x,若 y1=x^(x>>1),那么y1的第i位为1表示x的第i位与第i+1位有奇数个1,y1的第i位为0表示x的第i位与第i+1位有偶数个1。由于奇数、偶数都是在Abel{0,1}中算,因此直接继续对y1操作,即只关心奇偶。


因此y2=y1^(y1>>2),即y2的第i位表示x的第i位到第i+3位的1的个数的奇偶。


不断重复此过程,直至y5,y5的第i位表示x的第i位到第i+32位的1的个数的奇偶。y5的第0位即是答案。

int odd_number(unsigned x)函数代码如下:

#include 
#include 
#include 
using namespace std;



int odd_number(unsigned x){
    x=x^(x>>1);
    x=x^(x>>2);
    x=x^(x>>4);
    x=x^(x>>8);
    x=x^(x>>16);
    
    return x&0x1;
}


int main(){
    int k;
    while(cin>>k){
        cout<


再补充一点,另一种做法也可以,而且思路比上面的做法更加直接,读者可以自己体会。 思路和上面是一样的。

代码如下:

int odd_number(unsigned x){
    x=x^(x>>16);
    x=x^(x>>8);
    x=x^(x>>4);
    x=x^(x>>2);
    x=x^(x>>1);
    
    return x&0x1;
}



你可能感兴趣的:(ics)