1. 程式人生 > >位運算之巧解

位運算之巧解

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 }

位運算之巧解