zoukankan      html  css  js  c++  java
  • 51Nod 2107 二个奇数次(位运算)

    2107 二个奇数次

    1.0 秒 131,072.0 KB
    输入一个长度为n的数组,考虑所有不同的数字,有且只有2个数字出现了奇数次。

    比如对于1 2 3 1 2 3 1 2,我们考虑所有不同的数字1 2 3,有且只有1,2出现了奇数次(均为3次)

    输出这两个出现了奇数次的数字。

    先输出这两个数字中较小的,再输出较大的。

    1 <= n <= 100000

    1 <= a[i] <= 10^9

    输入

    第一行一个整数n,
    接下来一行n个整数,表示输入的数字。

    输出

    一行2个数字,表示出现了奇数次的数字,先输出小的,再输出大的。

    输入样例

    8
    1 2 3 1 2 3 1 2

    输出样例

    1 2

    解题思路:之前我们做过一个奇数次,即给定n个数,有且只有一个数出现了奇数次,输出这个数,在做那个题的时候直接一直异或运算就可以得到想要的数字(因为n^n等于0,而0和任何数异或都是数字本身,所以就很好求),这个题要求出现奇数次的两个数,肯定不能一直异或吧…思路:还是先将所有数异或在一起,最后一定会得到一个数,这个数是要求的两个数异或在一起,然后分成两组去求这两个数,具体怎么分呢?假设两个数异或在一起的二进制数R是110111000,我们知道异或以后1的位置就是两个数不一样的位置。我们进行这样一个操作:int lowbit=R&(-R),这个操作的用处在于找出最低位1的位置。R是110111000,而-R是001001000,(数字在计算机中是以补码的形式存储的)两个数&在一起,得出来的是1000这就是两个数不同的地方最低位1的位置,我们分两组:这一位是1的一组,0的一组,然后异或在一起,就很容易得到了。代码实现:

    #include <bits/stdc++.h>
    using namespace std;
    const int _max=1e5+5;
    int s[_max];
    int main()
    {
    	int n,r=0;
    	int a=0,b=0;
    	cin>>n;
    	for(int i=0;i<n;i++)
    	  cin>>s[i];
    	for(int i=0;i<n;i++)
    	  r^=s[i];
    	int lowbit=r&(-r);//找最低位1的位置
    	for(int i=0;i<n;i++)
    	  if(s[i]&lowbit)//分成两组分别异或
    	    a^=s[i];
    	  else
    	    b^=s[i];
    	cout<<min(a,b)<<" "<<max(a,b)<<endl;
    	return 0;	  
    }
    
  • 相关阅读:
    [原创] Laravel 启动流程
    修改电脑的TTL返回值
    Apache启动错误解决方法
    RemodelanyWhere11.0.2673版本下载
    函数指针
    指针与数组
    青蛙跳台阶
    旋转数组的最小数字
    对大量人的年龄排序
    泛型算法一
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294332.html
Copyright © 2011-2022 走看看