题目
题目描述
经过一段时间的紧张筹备,电脑小组的“RP餐厅”终于开业了,这天,经理LXC接到了一个定餐大单,可把大家乐坏了!员工们齐心协力按要求准备好了套餐正准备派送时,突然碰到一个棘手的问题,筷子!CX小朋友找出了餐厅中所有的筷子,但遗憾的是这些筷子长短不一,而我们都知道筷子需要长度一样的才能组成一双,更麻烦的是CX找出来的这些筷子数量为奇数,但是巧合的是,这些筷子中只有一只筷子是落单的,其余都成双,善良的你,可以帮CX找出这只落单的筷子的长度吗?
输入输出格式
输入格式:
第一行读入一个数N,它代表CX找到的筷子的根数。
第二行是N个用空格隔开的数,代表筷子的长度。
输出格式:
一行,落单的筷子的长度。
输入输出样例
输入样例#1:
9
2 2 1 3 3 3 2 3 1
输出样例#1:
2
说明
对于80%的数据,N<=100000;
对于100%的数据,N<=10000000。
【知识插入】异或
异或是对二进制位进行的操作。异或的基本口诀就是“相同得假,不同得真”,也就是0^1=1^0=1;1^1=0^0=0;
我们还可以得出一个规律:0和1异或0都不变,异或1则取反。
进一步,我们可以得出这样的结论:对于任何一个数A,都存在A^A=0,A^0=A。
分析
这道题目直到异或之后就很好做了。相同的筷子长度异或一下肯定是0,因此所有的成对筷子长度异或起来肯定是0,再和那个单独的筷子异或一下,就是那个单独筷子的长度了。所以……上代码:
代码
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int>p;
//以上是变量定义的部分,n用来存筷子的数量,p是一个vector类型,也就是不定长数组,用来存储筷子的长度。
int main()
{
scanf("%d",&n);
//率先读入n。
p.resize(n+1);
//这句语句的意思是给不定长数组vector类型的p分派n+1个空间(下标是0~n),vector的好处就在这里了,我们可以在程序的任意地方释放空间(.clear()),也可以在任意地方分配空间(.resize())。。这个stl很好用。
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
//读入筷子长度
for(int i=2;i<=n;i++)
p[i]=p[i]^p[i-1];
//逐个异或。
printf("%d",p[n]);
//最后的p[n]就是最终答案。
return 0;
}//本算法时间复杂度O(n),空间复杂度O(n).