异或运算的开关性

开关性是异或运算最重要的性质--同一个数异或两次以后相当于没有异或。

另外,异或还满足交换律,0与任何数异或的结果还是该数。

HDU5650点击打开原题链接

题目大意:给一个集合,将该集合的所有子集内的所有元素进行异或运算,输出其结果

    Input

This problem has multi test cases. First line contains a single integer  T(T20) which represents the number of test cases.
For each test case, the first line contains a single integer number  n(1n1,000) that represents the size of the given set. then the following line consists of  ndifferent integer numbers indicate elements( 109) of the given set.
Output
For each test case, print a single integer as the answer.
Sample Input
 
   
1 3 1 2 3
Sample Output
 
   
0
先给出代码:

#include 
int main()
{
	int t, x, n;
	
	scanf( "%d", &t);
	for ( int i = 1; i <= t; ++ i){
		scanf( "%d", &n);
		for ( int j = 1; j <= n; ++ j){
			scanf( "%d", &x);
		} 
		if ( n == 1){
			printf( "%d\n", x);
		}
		else
			printf( "0\n");
	}
	return 0;
}
当集合中所有元素在子集中出现的总次数均为2^(n - 1),只有当n=1时出现技术次,所以直接判断n是否等于1即可。


ZZUOJ10450: 找数点击打开原题链接

题目大意:

给一堆数,其中只有两个数只出现一次,其他的均出现两次,找出这两个数,并按从小到大的顺序输出

Input

每组样例第一行都是一个整数n,(n <= 2000000)代表这堆数的个数。 样例的第二行为n个整数e,代表着这堆数( 0 <= e < 100000000)保证除了两个数只出现一次之外,其他的数均是出现两个。

Output

按从小到大的顺序输出这两个数到一行,行末不能出现空格。

Sample Input

10
1 2 2 3 4 4 5 5 6 6

Sample Output

1 3
给出代码:

#include 
#define maxn 2000010
int a[maxn];
int main()
{
	int n, t, x, y, z;
	
	scanf( "%d", &n);
	x = 0;
	for ( int i = 0; i < n; ++ i){
		scanf( "%d", &a[i]);
		x ^= a[i];
	}	
	x &= -x;
	y = z = 0;
	for ( int i = 0; i < n; ++ i){
		if ( x & a[i])
			y ^= a[i];
		else
			z ^= a[i];
	}
	if ( y > z){
		t = y; y = z; z = t;
	}
	printf( "%d %d\n", y, z);
	return 0;
} 
首先利用异或运算得到的x便是这两个数异或的结果,将x与-x异或便得到x补码中位最低的1所对应的值(x中该位为1,则这两个数中必然只有1个该位为1,同树状数组中lowbit原理)

然后利用其,将所有数分为两堆,这两个数位于不同的堆,然后将两堆异或,得到的两个结果便是这两个数。



你可能感兴趣的:(平时训练,---部分分类---,基础算法)