数组中只出现一次的数字——位运算

http://ac.jobdu.com/problem.php?cid=1039&pid=22

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

问题1:如果是寻找只有一个出现一次的数字,比较简单的,只要所有数字异或一次即可

问题2:找出这两个只出现一次的数字,就要将所有的数字分成两堆,每堆个包含一个出现一次的数字:先把所有数字异或下得到一个数A,A的二进制中的某一位为1,这时就可以以所有数二进制某一位是否为1分成两堆,这是回到了问题一

数组中只出现一次的数字——位运算 View Code
#include<stdio.h>



int a[1000009];

int b[1000009],c[1000009];



template <class T>  

inline void scan_d(T &ret) {  

    char c; ret=0;  

    while((c=getchar())<'0'||c>'9');  

    while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();  

}



int main()

{

    

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        int i;

        for(i=1;i<=n;++i){

            scan_d(a[i]);

        }



        int left=a[1];

        for(i=2;i<=n;++i){

            left=left^a[i];

        }



        int addl=0,addr=0,add=0;

        while(((1<<add)&left)==0) ++add;;

        int temp=1<<add;



        for(i=1;i<=n;i++){

            if(a[i]&temp){++addl;

                b[addl]=a[i];

            }

            else{++addr;

                c[addr]=a[i];

            }

        }



        int min=b[1],max=c[1];

        for(i=2;i<=addl;++i){

            min=min^b[i];

        }

        for(i=2;i<=addr;++i){

            max=max^c[i];

        }



        if(min>max){

            temp=max;max=min;min=temp;

        }

        printf("%d %d\n",min,max);

    }



    return 0;

}

再输入加速,排到了第二

你可能感兴趣的:(位运算)