某公司上班使用打卡制度,员工须要在打卡机器上打入和打出才算上班。每一个员工都有本身对应编号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 }