zoukankan      html  css  js  c++  java
  • DLUTOJ1216

    题目大意是:给出 $N$ 个正整数,其中至多有一个数只出现一次,其余的数都出现了两次。判断是否有某个数只出现一次,若有输出这个数,否则输出“-1”。 $1\le N\le 5000000$

    这道题的正解是用位运算中的异或 XOR (^)

    位运算有一个重要性质:与顺序无关。

    证明:
    1^0=1, 0^0=0
    1^1=0, 0^1=1
    即0,1与0异或不变,与1异或取反,所以与0异或可以忽略。只考虑1。若 $m$ 个 0, $n$ 个 1 逐次取反,考虑把其中任一位置于开头,若开头是0,则结果为0取反 $n$ 次,若开头是1,则结果为1取反 $n-1$ 次,两者必然相等。所以异或运算是可任意交换位置,任意加括号的。

    至于这道题,若 $N$ 是偶数,必然没有只出现一次的数,若 $N$ 是奇数,根据上面的证明,将 0 与这 $N$ 个数逐次异或,最后得到的数就是只出现了一次的那个。异或运算不用特别考虑符号位,代码中 unsigned 型换成 int 也行。

    #include<cstdio>
    using namespace std;
    int main()
    {
        unsigned t;
        scanf("%u",&t);
        while(t--)
        {
            unsigned k=0, n, id;
            scanf("%u",&n);
            if(n%2==0)
            {
                for(int i=0; i<n; i++) scanf("%u",&id);//虽然到这步就可以直接判断但还是要接着读后面的数据
                printf("-1\n");
                continue;
            }
            for(int i=0; i<n; i++)
            {
                scanf("%u",&id);
                k^=id;
            }
            printf("%u\n",k);
        }
        return 0;
    }
  • 相关阅读:
    Toolbar设置回退箭头的方法
    Android进程绝杀技--forceStop
    线程池的经典使用
    Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式
    adb pull apk
    工厂模式_工厂方法模式
    工厂模式_简单工厂模式
    spring_aop
    代理模式_动态代理
    代理模式_静态代理
  • 原文地址:https://www.cnblogs.com/Patt/p/4031955.html
Copyright © 2011-2022 走看看