SDNU1541(二进制异或+统计两个出现的单独数字)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
const int maxn=1e6+5;
int num[maxn];
int T,n;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        int sum=0;
        int maxp=0,minp=0;
        for(int i=0; i<n; ++i)
        {
            scanf("%d",&num[i]);
            sum^=num[i];
        }
        int t=1;
        while((t&sum)==0)
        {
            t<<=1;
        }
        for(int i=0; i<n; ++i)
        {
            if((num[i]&t)==0)
            {
                maxp^=num[i];
            }
        }
        minp=sum^maxp;
        if(minp>maxp)
            printf("%d %d\n",maxp,minp);
        else
            printf("%d %d\n",minp,maxp);
    }
    return 0;
}

1.【算法思想】利用最终异或和二进制位从右到做第一个为1的位置:将整个数组所有值分为两类。一类数字在该位置二进制为0,另一类在该位置二进制为1。注意到两个单独出现的数字在这个位置的二进制位一定是不同的。(二进制异或相异为1)所以归为两类之中。两类数字分别异或的结果就是两个数字。

2.注意语法表达的错误(两处):

        while((t&sum)==0)
        {
            t<<=1;
        }

【知识点1】==运算符的优先级高于&因此,上面的语句不能写成下面的形式:

        while(t&sum==0)
        {
            t<<=1;
        }

【知识点2】t<<=1;是t二进制左移一位的正确表达式。

下面是错误的表达式:

  while((t&sum)==0)
        {
            t<<1;
        }

附上一张证明优先级的截图: 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值