解决找数字问题
奇数个的那个数
给定些数字,这些数中只有一个数出现了奇数次,找出这个数。
Input
每组数据第一行n表示数字个数,1 <= n <= 2 ^ 18 且 n % 2 == 1。
接下来n行每行一个32位有符号整数。
Output
出现奇数次那个数,每组数据对应一行。
Sample Input
5
1
1
2
2
3
7
1
2
1
2
2
3
3
Sample Output
3
2
这里可以用异或(异或_ :http://baike.baidu.com/link?url=rObpv9NerpblUhee9BnU9H837A4yJmYByTxKgUic8dESAl9Bv32F61diLFYFChaIaGJsLw0jMF-m3L6IHXzkeq)来解决。
异或运算的几个性质:
1、A xor A = 0,也就是说异或同一个数偶数次,结果不变。
2、异或运算满足交换律。
这样我们只需要按顺序把所有的数依次异或一遍,剩下的就是唯一出现奇数次的那个数了。
代码:
#include<cstdio> using namespace std; int n,ans=0; int main() { while(scanf("%d",&n)!=EOF) { int x; ans=0; while(n--) { scanf("%d",&x); ans^=x; } printf("%d\n",ans); } return 0; }还有一个更加复杂的问题,就是有2个数字出现奇数次,当然,这里n就是偶数了,该如何解决呢?
假设这两个数为a,b,将数组中所有元素异或结果x=a^b,判断x中位为1的位数(注:因为a!=b,所以x!=0,我们只需知道某一个位为1的位数k,例如0010 1100,我们可取k=2或者3,或者5),然后将x与数组中第k位为1的数进行异或,异或结果就是a,b中一个,然后用x异或,就可以求出另外一个。
为什么呢?因为x中第k位为1表示a或b中有一个数的第k位也为1,假设为a,我们将x与数组中第k位为1的数进行异或时,也即将x与a外加其他第k位为1的出现过偶数次的数进行异或,化简即为x与a异或,结果是b。
代码:
#include<cstdio> using namespace std; int a[1000005]; int main() { int n,ans1,ans2,x; while(scanf("%d",&n)!=EOF) { x=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); x^=a[i]; } ans1=x;ans2=x; int k=0; while(!(ans1&1))//注意一定要用括号,因为优先级不一样 { ans1>>=1; k++; } for(int i=0;i<n;i++) { if((a[i]>>k)&1) { x^=a[i]; } } printf("%d %d\n",x,(x^ans2)); } return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步