zoukankan      html  css  js  c++  java
  • 九度oj 题目1256:找出两个只出现了一次的数字

    题目描述:

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

    输入:

    输入的第一行包括一个整数N(1<=N<=1000)。
    接下来的一行包括N个整数。

    输出:

    可能有多组测试数据,对于每组数据,
    找出这个数组中的两个只出现了一次的数字。
    输出的数字的顺序为从小到大。

    样例输入:
    6
    2 3 9 3 7 2 
    样例输出:
    7 9

    (题目中的条件 N 应该大于1)
    开始的想法是先排序,然后再去数数,代码如下
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 int cmp(const void *a, const void *b) {
     7     int at = *(int *)a;
     8     int bt = *(int *)b;
     9     return at-bt;
    10 }
    11 
    12 int n;
    13 int tmp[1002];
    14 
    15 int main(int argc, char const *argv[])
    16 {
    17     while(scanf("%d",&n) != EOF) {
    18         for(int i = 0; i < n; i++) {
    19             scanf("%d",&tmp[i]);
    20         }
    21         qsort(tmp,n,sizeof(int),cmp);
    22         int i = 0;
    23         int cnt = 0;
    24         int ans1 = 0, ans2 = 0;
    25         while(i < n) {
    26             if((i == n-1) || tmp[i] != tmp[i+1]) {
    27                 if(cnt == 0) {
    28                     ans1 = tmp[i];
    29                     cnt++;
    30                 }
    31                     
    32                 else {
    33                     ans2 = tmp[i];
    34                     cnt++;
    35                     break;
    36                 }
    37 
    38                 i++;
    39                 
    40             }
    41             else {
    42                 i += 2;
    43             }
    44         }
    45         printf("%d %d
    ",ans1, ans2);
    46         
    47     }
    48     return 0;
    49 }

    虽然通过了,但耗时较长,几乎已达上限

    之后改成用异或的方法来做

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 
     7 int n;
     8 int tmp[1002];
     9 
    10 int main(int argc, char const *argv[])
    11 {
    12     int yi = 0;
    13     while(scanf("%d",&n) != EOF) {
    14         yi = 0;
    15         for(int i = 0; i < n; i++) {
    16             scanf("%d",&tmp[i]);
    17             yi = yi ^ tmp[i];
    18         }
    19         int cnt = 0;
    20         while((yi & 1) == 0) {
    21             yi = yi >> 1;
    22             cnt++;
    23         }
    24         int ans1 = 0, ans2 = 0;
    25         for(int i = 0; i < n; i++) {
    26             int ct = 0;
    27             int p = (tmp[i] >> cnt)&1;
    28             if(p == 0) {
    29                 ans1 = ans1 ^ tmp[i];
    30             }
    31             else {
    32                 ans2 = ans2 ^ tmp[i];
    33             }
    34         }
    35         if(ans1 > ans2) {
    36             int temp = ans1;
    37             ans1 = ans2;
    38             ans2 = temp;
    39         }
    40         printf("%d %d
    ",ans1,ans2);
    41     }
    42     return 0;
    43 }

    所有的异或后为那两个数异或的结果,再按该结果对原数据进行分组,将两个数分到不同的组内,再进行异或就会得出两个数。

  • 相关阅读:
    BZOJ 1003 物流运输
    549565
    26566
    68
    554554
    5656
    49886
    5989
    6898
    656
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5770421.html
Copyright © 2011-2022 走看看