• BUPT OJ84 SINGLE NUMBER


    题目描述

    Given an array with N integers where all elements appear three times except for one. Find out the one which appears only once.

    输入格式

    Several test cases are given, terminated by EOF.

    Each test case consists of two lines. The first line gives the length of array N(1N105), and the other line describes the Nelements. All elements are ranged in [0,2631].

    输出格式

    Output the answer for each test case, one per line.

    输入样例

    4
    1 1 1 3
    10
    1 2 3 1 2 3 1 2 3 4

    输出样例

    3
    4

     

    超时的代码:

    #include <stdio.h>
    #define MAX 100000
    int main()
    {
        int N;
        int a[MAX];
        int i,j;
        int count[MAX];    
        while( scanf("%d",&N)!=EOF)
        {
            
            for(i=0;i<N;i++)
        {
            scanf("%d",&a[i]);
        } 
        for(i=0;i<N;i++)
        {
            count[i]=0;
            for(j=0;j<N;j++)
           {
                  if(a[i]==a[j])
                     count[i]++;
           }
        }       
        for(i=0;i<N;i++)
           if(count[i]==1)
             printf("%d
    ",a[i]);
        } 
        
    }

    网上另类的思路:

    http://blog.csdn.net/birdstorm_s/article/details/19967311

    主要思路是对所有数字进行异或运算, 模拟二进制加法

     因为异或运算有a⊕b⊕a=b这样的性质, 所以可以设app_1, app_2代表出现一次和两次的数, 用not_three代表所有没有出现三次的数, 通过位运算, 最后app_2和出现三次的数被清0, 只剩下app_1, 也就是结果

    有人提到前面解释不清楚,那我更新一下。异或运算本质是二进制位运算,app_1保留出现奇数次的数,一旦出现两次就将进入app_2并从app_1中擦除,如果出现三次就会因为同时出现在app_1和app_2中而被not_three擦除,每次app_1和app_2都要和not_three进行一次与运算确保app_1和app_2中没有存放大于等于三次的数, 所以最终保留的app_1就是只出现一次的数。这个办法通过改变变量个数可以满足一切的查找唯一出现次数的问题,可设app[]进行保存。

    算法复杂度是O(n)

    #include<stdio.h>  
       
    main()  
    {  
        long long x, n, app_1, app_2, not_three;  
        while(scanf("%lld",&n)!=EOF){  
            app_1=0, app_2=0;  
            while(n--){  
                scanf("%lld",&x);  
                app_2 |= app_1&x;  
                app_1 ^= x;  
                not_three = ~(app_1&app_2);  
                app_1 = not_three&app_1;  
                app_2 = not_three&app_2;  
            }  
            printf("%lld
    ",app_1);  
        }  
        return 0;  
    }  
  • 相关阅读:
    P1829 [国家集训队]Crash的数字表格 / JZPTAB 莫比乌斯反演
    Luogu P1447 [NOI2010]能量采集 数论??欧拉
    Luogu P2522 [HAOI2011]Problem b 莫比乌斯反演
    Luogu P2257 YY的GCD 莫比乌斯反演
    [笔记] 数论函数小记
    [笔记] 线性筛小记
    Luogu P1092 虫食算 爆搜
    Luogu P1066 2^k进制数 组合数学
    Luogu P1641 [SCOI2010]生成字符串 组合数学
    Luogu P2532 [AHOI2012]树屋阶梯 卡特兰数
  • 原文地址:https://www.cnblogs.com/lipching/p/6402252.html
Copyright © 2020-2023  润新知