看似很水的题--找画笔

解题报告 2019-8-8

1.豆豆对数字的执着,让他在理科领域游刃有余,但他近乎疯狂的投入也使父母有些担心,为了让孩子能够全面发展,决定拓宽他的学习领域,正好家旁边有个绘画培训中心就给豆豆报了名,学习绘画的第一天就让豆豆产生了浓厚的兴趣,还主动要求买了很多很多的画笔,画笔有多种颜色,豆豆有一个习惯就是同种颜色的画笔就买两支,一支备用,就这样总共攒了 NN 支画笔( NN 是偶数且 1<N<1061<N<106 )。可是数字的敏感无孔不入,豆豆脑里蹦出了一个奇怪的问题:如果蒙上眼任意拿走一支画笔,分析剩下的 N−1N−1 支画笔找出拿走了哪种颜色,你能回答他吗?

输入

第一行一个整数表示剩下的画笔个数就是题目描述中的 N−1N−1 。
第二行 N−1N−1 个用空格隔开的正整数 Ai(1≤Ai<231)Ai(1≤Ai<231) ,表示剩下的画笔的颜色编号。
注意:数据保证有一个画笔的颜色 编号出现了一次,其余的都出现了两次。

输出

一行一个整数 PP ,表示拿走的画笔的颜色编号。

据说是一个公司面试题哦......

首先,你肯定会想到一种方法:我们新开个数组cnt。每输入一个a[i],cnt[a[i]]++;到最后看谁==1;
好,先恭喜你自己,想到了一种解法。
其次,恭喜你,这家公司是死也不可能要你了。。。你就想出这么个辣鸡方法来??等着空间溢出吧。。。

在冷静下来一想,我们可以先对数组进行排序。遍历数组每个元素,找下去绝对没问题。
代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,a[1000010];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i+=2)
        if(a[i]!=a[i+1]){
            printf("%d\n",a[i]);
            return 0;
        }
    return 0;
}

再次恭喜您,想到能AC的代码了,但是,公司还是不会要你。

因为你不够骚,不够快。

这种做法是O(nlogn)慢死了。
所以,教你一种骚操作:位运算。
你把数组中每个数字异或起来,就是你要输出的结果了。(我赌你没听懂)
我来解释一下:首先,异或(^) 他是把数字每一位转成2进制,对于每个2进制位:
0^0=0 0^1=0 1^0=0 1^1=1
那么,就很容易理解a^a=0。那么,其他相同的每一位都异或起来,等于设么事都没发生。那么,你最终的结果就是------你要找的数!!!!!!!!!!!!!!!!!!!!!!!!!!

猜你喜欢

转载自www.cnblogs.com/tushukai/p/11324218.html