黑暗意志(异或)

Description

👉ZCMU:1977

题目的大致意思是场上有许多血量不同的小魔像,当存在两只小魔像血量相同时,两者之间会产生连线从而降低伤害输出的比例。玩家的任务便是使尽可能多的小魔像配对,两只小魔像的血量相同就算配对成功。

Input

第一行一个整数T,代表数据的组数(1<=T<=10),接下来T组数据,每组数据的第一行是一个整数n(2<=n<=1000000,保证n是偶数),第二行是n个整数ai(0 <= ai <= 1000000000)代表血量,每两个整数之间有一个空格,(输入保证有且只有两个小魔像无法连线)

Output

对于每组数据,输出两个整数,分别代表两个小魔像的血量,中间有一个空格,并且血量较大的先输出。

Sample Input

2

6

2 2 1 1 3 4

4

4 1 1 3 4

Sample Output

4 3

4 3

Analysis

结合题目的输入输出可知,我们需要在给出的数据中找出两只无法配对的小魔像。这里采用异或的方式求解。

因为一个数与同一个数进行两次异或运算值不变,比如3^5^5=3

011
^101
110
^101
011

将一组数据与0进行异或运算,最后得到的sum就是其中唯一两个不配对的数据的异或结果。while(((sum>>f)&1)==0) f++;通过将结果不断右移并与1相与,就可以得到这两个数字的最低不同数位,即第f位(f从0开始计数)。比如第一个组数据得到的sum=3^4=111(2)

111
&001
001

条件(sum>>0)&1为假,得到第0位为最低位。然后以第f位(f=0)是否位0做条件将数据分为两组分别进行异或运算,使得两个不同的数分开,最后将结果排序输出。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
long long a[maxn];
int main(){
    int t,n;
    cin>>t;
    while(t--){
        cin>>n;
        int sum=0;
        for(int i=0;i<n;i++){
            cin>>a[i];
            sum^=a[i];
        }
        int f=0;
        while(((sum>>f)&1)==0) //注意优先级
            f++;
        int x=0,y=0;
        for(int i=0;i<n;i++){
            if((a[i]>>f)&1) x^=a[i];
            else y^=a[i];
        }
        if(x<y) swap(x,y);
        cout<<x<<" "<<y<<endl;
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值