九度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\n",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\n",ans1,ans2);
41     }
42     return 0;
43 }

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

转载于:https://www.cnblogs.com/jasonJie/p/5770421.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值