灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:3917回复:0

[C++技术]找出两个只出现一次的数

楼主#
更多 发布于:2013-06-17 10:52
前言
周末和大学的几个伙计聚了一下,很开心,大家都很懂事而且都在努力,已经有两年硕士毕业去雅虎的,薪资待遇更是没得说,哈哈,聊得很开心,不过周末没怎么写代码,这里在九度oj水几道题,顺便记录一下(ps:貌似这个题目之前有记录过,不管了)


题目
[html]
题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
输入:
输入的第一行包括一个整数N(1<=N<=1000)。
接下来的一行包括N个整数。
输出:
可能有多组测试数据,对于每组数据,
找出这个数组中的两个只出现了一次的数字。
输出的数字的顺序为从小到大。
样例输入:
6
2 3 9 3 7 2  
样例输出:
7 9

题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
输入:
输入的第一行包括一个整数N(1<=N<=1000)。
接下来的一行包括N个整数。
输出:
可能有多组测试数据,对于每组数据,
找出这个数组中的两个只出现了一次的数字。
输出的数字的顺序为从小到大。
样例输入:
6
2 3 9 3 7 2
样例输出:
7 9


思路
这里主要考察c的位运算,介绍两个异或运算的性质:
任何一个数字异或它自己都等于0
任何一个数字(除0外)异或0都等于它本身
所以我们可以考虑如下思路:
从头到尾异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果
由于两个数字肯定不一样,那么异或结果肯定不全为0,找出第一个为1的位置,记为loc
通过判断数组每个数的loc位是否为1,将数组分为两部分
两部分数组分别异或即可


ac代码
[cpp]
#include <stdio.h>  
#include <stdlib.h>  
  
int firstone_loc(int num)
{
    int i;
    for (i = 0; num % 2 == 0; i ++) {
        num = num >> 1;
    }
  
    return i;
}
  
int judge_loc(int num, int loc)
{
    num = num >> loc;
    if (num % 2 == 1) {
        return 1;
    } else {
        return 0;
    }
}
  
int main(void)
{
    int i, n, unique, first, second, loc, flag, *arr;
  
    while (scanf("%d", &n) != EOF) {
        arr = (int *)malloc(sizeof(int) * n);
        for (i = unique = 0; i < n; i ++) {
            scanf("%d", arr + i);
            unique ^= arr;  
        }
  
        // 第一个为1的位  
        loc = firstone_loc(unique);
  
        for (i = first = second = 0; i < n; i ++) {
            flag = judge_loc(arr, loc);
            if (flag) {
                first ^= arr;
            } else {
                second ^= arr;
            }
        }
  
        if (first < second) {
            printf("%d %d\n", first, second);
        } else {
            printf("%d %d\n", second, first);
        }
  
        free(arr);
    }
  
    return 0;
}
/**************************************************************
    Problem: 1256
    User: wangzhengyi
    Language: C
    Result: Accepted
    Time:570 ms
    Memory:912 kb
****************************************************************/

#include <stdio.h>
#include <stdlib.h>
 
int firstone_loc(int num)
{
    int i;
    for (i = 0; num % 2 == 0; i ++) {
        num = num >> 1;
    }
 
    return i;
}
 
int judge_loc(int num, int loc)
{
    num = num >> loc;
    if (num % 2 == 1) {
        return 1;
    } else {
        return 0;
    }
}
 
int main(void)
{
    int i, n, unique, first, second, loc, flag, *arr;
 
    while (scanf("%d", &n) != EOF) {
        arr = (int *)malloc(sizeof(int) * n);
        for (i = unique = 0; i < n; i ++) {
            scanf("%d", arr + i);
            unique ^= arr;
        }
 
        // 第一个为1的位
        loc = firstone_loc(unique);
 
        for (i = first = second = 0; i < n; i ++) {
            flag = judge_loc(arr, loc);
            if (flag) {
                first ^= arr;
            } else {
                second ^= arr;
            }
        }
 
        if (first < second) {
            printf("%d %d\n", first, second);
        } else {
            printf("%d %d\n", second, first);
        }
 
        free(arr);
    }
 
    return 0;
}
/**************************************************************
    Problem: 1256
    User: wangzhengyi
    Language: C
    Result: Accepted
    Time:570 ms
    Memory:912 kb
****************************************************************/
这里需要提示一下,由于我本身对位运算也不够熟悉,因为我判断第i位是否为1,是用%2是否为1判断的,其实如果对位运算熟悉,直接&1即可


按照上述方法的ac代码


[cpp]
#include <stdio.h>  
#include <stdlib.h>  
  
int firstone_loc(int num)
{
    int i;
    for (i = 0; (num & 1) == 0; i ++) {
        num = num >> 1;
    }
  
    return i;
}
  
int judge_loc(int num, int loc)
{
    num = num >> loc;
      
    return (num & 1);
}
  
int main(void)
{
    int i, n, unique, first, second, loc, flag, *arr;
  
    while (scanf("%d", &n) != EOF) {
        arr = (int *)malloc(sizeof(int) * n);
        for (i = unique = 0; i < n; i ++) {
            scanf("%d", arr + i);
            unique ^= arr;  
        }
  
        // 第一个为1的位  
        loc = firstone_loc(unique);
  
        for (i = first = second = 0; i < n; i ++) {
            flag = judge_loc(arr, loc);
            if (flag) {
                first ^= arr;
            } else {
                second ^= arr;
            }
        }
  
        if (first < second) {
            printf("%d %d\n", first, second);
        } else {
            printf("%d %d\n", second, first);
        }
  
        free(arr);
    }
  
    return 0;
}
  
/**************************************************************
    Problem: 1256
    User: wangzhengyi
    Language: C
    Result: Accepted
    Time:560 ms
    Memory:912 kb
****************************************************************/

#include <stdio.h>
#include <stdlib.h>
 
int firstone_loc(int num)
{
    int i;
    for (i = 0; (num & 1) == 0; i ++) {
        num = num >> 1;
    }
 
    return i;
}
 
int judge_loc(int num, int loc)
{
    num = num >> loc;
    
    return (num & 1);
}
 
int main(void)
{
    int i, n, unique, first, second, loc, flag, *arr;
 
    while (scanf("%d", &n) != EOF) {
        arr = (int *)malloc(sizeof(int) * n);
        for (i = unique = 0; i < n; i ++) {
            scanf("%d", arr + i);
            unique ^= arr;
        }
 
        // 第一个为1的位
        loc = firstone_loc(unique);
 
        for (i = first = second = 0; i < n; i ++) {
            flag = judge_loc(arr, loc);
            if (flag) {
                first ^= arr;
            } else {
                second ^= arr;
            }
        }
 
        if (first < second) {
            printf("%d %d\n", first, second);
        } else {
            printf("%d %d\n", second, first);
        }
 
        free(arr);
    }
 
    return 0;
}
 
/**************************************************************
    Problem: 1256
    User: wangzhengyi
    Language: C
    Result: Accepted
    Time:560 ms
    Memory:912 kb
****************************************************************/


对比

喜欢0 评分0
游客

返回顶部