闲来无事,水一篇题解
题目:
|
问题描述
给你n个整数,里面有很多重复的数。其中只有一个数出现了奇数次,其他都是偶数次。现在要你找出这个数。
输入格式
第一行一个整数n。
第二行n个整数。
输出格式
一个正整数,出现奇数次的那个数。
样例输入
样例输入1:
5
2 7 4 2 7
样例输入2:
9
7 8 8 7 7 8 2 8 2
样例输出
样例输出1:
4
样例输出2:
7
提示
1<=n<=1e6,显然n会是个奇数
0<=每个数<=1e18
注意内存限制。
题目非常简洁明了,但提示说了,注意内存限制,显然不能开数组,那怎么办呢???
!!!
传说C++里有种非常厉(niu)害(bi)的东西
它比普通的加减乘除快,可靠性高,运算规则简单,最重要的是,它可以解决这题内存不够的痛点
他就是————————位运算
首先,我们得明白位运算的运算规则:
按位与(&) 1&1=1,1&0=0,0&1=0,0&0=0
按位或(|) 1|1=1 1|0=1 0|1=1 0|0=0
取反 (~) 0变1 1变0
异或(^) 这道题需要用到的运算符 0^0=0 1^1=0 0^1=1 1^0=1
有两个很重要的性质:
1. 任何数异或零等于它本身
2. 任何数异或他自己等于零
注意:这里提到的只是部分位运算符,其他的请自行了解
有了这两个性质,题目就简单了起来,那么我们不妨用一个变量x来存这些数,每输入一个x,ans就异或上x
通过性质2,我们知道那些只出现偶数次的数都变零了,只剩一个孤零零的那个只出现奇数次的数,而之出现奇数次的数的那些多余的次数,也变成零了
于是,就只剩下了那个只出现奇数次的数和一堆零,根据性质1,可以得到ans就是最终答案
时间复杂度O(n),空间复杂度O(1),完美!
代码( 我知道你们只看这个 ):
#include <iostream>
using namespace std;
long long n,x,ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=0; i<n; i++){
cin>>x;
ans^=x;
}
cout<<ans;
return 0;//华丽结束
}
求个赞,求个关呀!!!