本題棘手的地方在於不能用循環語句,並且最多隻能包含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 <iostream>
#include <cstdio>
#include <cstring>
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<<odd_number(k)<<endl;
}
}
再補充一點,另一種做法也可以,而且思路比上面的做法更加直接,讀者可以自己體會。 思路和上面是一樣的。
代碼如下:
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;
}