NOJ [1314] Brave Sword [1416] Clear Up

这两题换汤不换药

都是相当于求出在数组里只出现一次的数

其实有很多方法,例如哈希,位运算

我用的是位运算的异或运算


a.先把所有数异或一遍,因为其他数相同,异或值为0,那么最后的异或值就是那两个只出现一次的数的异或值。

b.得到那个异或值以后,分析,既然这两个数不一样,那么异或以后必不为0,换句话说,在那个值对应的二进制数的某一位,一定是1。

c.这样的话,那一位上两个数一定不一样例如1110,1010,第二位不一样,异或后那一位才会为1.

d,这样我们就得到了划分的标准,接下来,把数组分成2份,分别是1.那一位上为1的、2.那一位上是0的

e.然后分别进行异或运算,得到的异或值就是那两个数


#include<stdio.h>

int allnum[1000000];
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		int i,j,s=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&allnum[i]);
			s^=allnum[i];
		}
		int first;
		//寻找xor第一位为1的位置
		for(i=0;i<32;i++)
		{
			if((s>>i)%2==1)
			{
				first=i;
				break;
			}
		}
		int one=0,another=0;
		for(i=0;i<n;i++)
		{
			if((allnum[i]>>first)%2==1)
			   one^=allnum[i];
            else
               another^=allnum[i];
		}
		printf("%d %d\n",one<another?one:another,one>another?one:another);
	} 
	return 0;
}


你可能感兴趣的:(NOJ [1314] Brave Sword [1416] Clear Up)