某公司上班使用打卡制度,員工須要在打卡機器上打入和打出纔算上班。每一個員工都有本身對應編號K,編號爲一個整數(1 <= K <=50000),某天有一員工忘記了一次打出。如今給你當天員工的打卡信息,你能找出該員工的編號嗎?
輸入包含多組測試,第一行包含數字N,表示公司的人數(1<=N<=50000)。第二行有2N-1個數,兩兩之間有空格,表示全部員工的打卡記錄。輸入N爲0則退出程序,不作輸出。
對於每組測試,單獨一行輸出忘記打卡員工的編號。
4 10 12 9 12 250 9 10
250
解題思路:給出2n-1個數,其中有n個數出現的次數都爲2,剩下的1個數出現的次數爲1,要求快速找出這個數。經過異或運算的特色可知,①本身異或自己的值爲0,②任何數和0異或都爲其自己。所以異或全部出現次數爲2的數最終的值爲0,那麼就只剩下出現次數爲1的元素。
AC代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,ans; 4 int main(){ 5 while(cin>>n&&n){ 6 n=2*n-1,ans=0; 7 while(n--){cin>>x;ans^=x;} 8 cout<<ans<<endl; 9 } 10 return 0; 11 }
小白最近刷聽力,刷出了一個大麻煩。不知爲什麼刷出了負分,小白只能向大白求助。 無奈大白翻車了。因此小白向小光師公求助,小光師公說只要你幫我解決了下面這道題目, 我就幫你刷回正分。無奈小白不會,只能交給聰明的你來解決了。 數組A中,除了某一個數字x以外,其餘數字都出現了三次, 而x出現了一次。請給出最快的方法找到x。
先輸入n,表示要輸入n個數字。( 0< n < 10^8) 而後輸入n個數字m。(-10^8)< m <(10^8)
輸出x
10 2223 1 1 2223 1 -111 1 2223 1 1 4 5 5 5 -6
-111 -6
解題思路:給出n個數,其中有(n-1)/3個數出現的次數都爲3,剩下的1個數出現的次數爲1,要求快速找出這個數。考慮每一個數的二進制,由於每一個數出現的次數都爲3,因此32位二進制中每一個bit上'1'的統計結果均可以被3整除,不然就是出現次數爲1的數在這個bit上貢獻出多餘的1。所以,將每一個數轉化成其二進制,而且統計每一個bit上1的個數,而後累加某個bit上不能被3整除的十進制數1<<bit,最終便可獲得出現次數爲1的數字。
推廣一下,全部其餘數字出現n(n>=2)次,而一個數字出現1次均可以用這種解法來推導出這個出現1次的數字。
AC代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,ans,bits[32]; 4 int main(){ 5 while(~scanf("%d",&n)){ 6 ans=0;memset(bits,0,sizeof(bits)); 7 for(int i=1;i<=n;++i){ 8 scanf("%d",&x); 9 if(!x)continue; 10 for(int j=0;j<32;++j)bits[j]+=((x>>j)&1);//要用右移操做,便於正確計算和避免溢出 11 } 12 for(int i=0;i<32;++i) 13 if(bits[i]%3!=0)ans+=(1<<i);//累加二進制上對應的值 14 printf("%d\n",ans); 15 } 16 return 0; 17 }
題解報告:NYOJ #744 螞蟻的難題(一)c++
小螞蟻童鞋最近迷上了位運算,他感受位運算很是神奇。不過他最近遇到了一個難題:數組
給定一個區間[a,b],在區間裏尋找兩個數x和y,使得x異或y最大。來,幫幫他吧!測試
有多組測試數據(以EOF結尾)。
每組數據輸入兩個數a,b.(0<=a<b<2^63)。spa
輸出a到b之間,異或最大的值。code
1 2 8 9
3 1
解題思路:爲了異或獲得最大值,咱們應選擇某兩個數的二進制位是互補的,而且其中一個數的二進制最高位的'1'是區間全部數的二進制中相對較高位的'1',這樣就能獲得全是1的二進制數,其位數爲bits,則獲得的異或值爲2bits-1。因而,經過異或區間左右端點的值a^b能夠發現,若是a和b二進制的前幾位是相同的,那麼在a到b的全部數中,這前幾位都不會改變,即不管選什麼數進行異或,這前幾位都是0,然後面的每一個bit裏0和1均可能出現,而且必定能找到互補的兩個數使其異或後後面的幾個bit都是1,這即可獲得最大值;同理若是a、b的最高位不一樣,那麼此時取決於b的二進制位數,由於b中某些bit爲0的位必定能經過區間中某個數的二進制bit進行'1'互補,即獲得全爲1的那幾位。所以只須要找到a和b的二進制從高位日後數第一個不相同的位,而後若是餘下m位,那麼答案就是2m-1。blog
AC代碼:ip
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL;LL a,b; 4 LL get_bits(LL x){//獲得異或的值的二進制位數 5 LL bits=1; 6 while(x>>=1)bits++; 7 return bits; 8 } 9 int main(){ 10 while(cin>>a>>b){ 11 cout<<((1LL<<get_bits(a^b))-1)<<endl;//2^n-1 12 } 13 return 0; 14 }