位運算之巧解
阿新 • • 發佈:2018-10-21
c代碼 所有 題目 sca bsp return put 忘記 十進制數
上班打卡
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
某公司上班使用打卡制度,員工需要在打卡機器上打入和打出才算上班。每個員工都有自己對應編號K,編號為一個整數(1 <= K <=50000),某天有一員工忘記了一次打出。現在給你當天員工的打卡信息,你能找出該員工的編號嗎?
Input:
輸入包含多組測試,第一行包含數字N,表示公司的人數(1<=N<=50000)。第二行有2N-1個數,兩兩之間有空格,表示所有員工的打卡記錄。輸入N為0則退出程序,不做輸出。
Output:
對於每組測試,單獨一行輸出忘記打卡員工的編號。
Sample Input:
4 10 12 9 12 250 9 10
Sample Output:
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 }
小白刷分記(二)
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
小白最近刷聽力,刷出了一個大麻煩。不知為何刷出了負分,小白只能向大白求助。 無奈大白翻車了。所以小白向小光師公求助,小光師公說只要你幫我解決了下面這道題目, 我就幫你刷回正分。無奈小白不會,只能交給聰明的你來解決了。 數組A中,除了某一個數字x之外,其他數字都出現了三次, 而x出現了一次。請給出最快的方法找到x。
Input:
先輸入n,表示要輸入n個數字。( 0< n < 10^8) 然後輸入n個數字m。(-10^8)< m <(10^8)
Output:
輸出x
Sample Input:
10 2223 1 1 2223 1 -111 1 2223 1 1 4 5 5 5 -6
Sample Output:
-111 -6
解題思路:給出n個數,其中有(n-1)/3個數出現的次數都為3,剩下的1個數出現的次數為1,要求快速找出這個數。考慮每個數的二進制,因為每個數出現的次數都為3,所以其二進制每位bit上1的個數肯定為3的倍數,否則就是出現次數為1的數在這個二進制bit位上貢獻出多余的1。因此,先將每個數轉化成32位的二進制,並且統計每位bit上1的個數,然後累加某位bit上不能被3整除的十進制數1<<bit後即可得到出現次數為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 }
位運算之巧解