容器+位异或 HDU 2095 find your parents(2)

本文介绍了一种在一组数字中找到唯一出现奇数次的数字的方法。利用STL容器如set进行存储和处理,以及更高效的位异或操作来解决此问题。


转载自:http://blog.youkuaiyun.com/dgq8211/article/details/7455722


题目链接:Click here~~

题意:

给你n个数字,已知只有一个数字出现了奇数次,其他数字都出现了偶数次,要求你找出这个特别的数字。

解题思路:

题目内存限制:1024K,所以不能简单地用数组存然后再处理。

为了节约内存,可以用STL里面的set,map等容器。

当容器里没有这个元素的时候,就插入这个元素,否则,删除这个元素。

最后,容器中肯定只剩下一个元素,便是我们所要的结果。

[cpp]  view plain  copy
  1. #include <set>  
  2. #include <stdio.h>  
  3. using namespace std;  
  4. int main()  
  5. {  
  6.     int n,x;  
  7.     set <int> S;  
  8.     while(scanf("%d",&n),n)  
  9.     {  
  10.         while(n--)  
  11.         {  
  12.             scanf("%d",&x);  
  13.             if(S.find(x) == S.end())    //没找到,插入  
  14.                 S.insert(x);  
  15.             else                        //找到了,删除  
  16.                 S.erase(x);  
  17.         }  
  18.         printf("%d\n",*S.begin());  
  19.         S.clear();  
  20.     }  
  21.     return 0;  
  22. }  

其实,这题还有个更好的方法————位异或。

我们先了解一下位异或的运算法则吧:

1、a^b = b^a。

2、(a^b)^c = a^(b^c)。

3、a^b^a = b。

对于一个任意一个数n,它有几个特殊的性质:

1、0^n = n。

2、n^n = 0。

所以可以通过每次异或运算,最后剩下的值就是出现奇数次的那个数字。

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4.     int n,x,ans;  
  5.     while(scanf("%d",&n),n)  
  6.     {  
  7.         ans = 0;  
  8.         while(n--)  
  9.         {  
  10.             scanf("%d",&x);  
  11.             ans ^= x;  
  12.         }  
  13.         printf("%d\n",ans);  
  14.     }  
  15.     return 0;  
  16. }  
PS:话说通过位运算的这些性质,可以通过不借用中间变量实现a,b的值的交换。

[cpp]  view plain  copy
  1. void swap(int &a,int &b)  
  2. {  
  3.     a ^= b;  
  4.     b ^= a;  
  5.     a ^= b;  
  6. }  

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值