比赛链接:
河南萌新联赛2024第(四)场:河南理工大学_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)
B题:小雷的神奇电脑
题目描述:
小雷有一台特殊的电脑,这台电脑有一个 m位的寄存器,能够存储一个m 位的二进制数。换句话说,这台电脑可以存储一个从0到 2^m -1之间的任何非负整数。
小雷还有一组n个非负整数的列表(中每一个数都严格小于2^m)。他想要找出这个列表中任意两个不同的数(下标不同就行),将它们放入电脑中进行同或运算后,得到的结果是所有可能的同或结果中最大的那个。
同或运算解释
同或运算(XNOR)是一种逻辑运算,它接受两个二进制位作为输入,并根据以下规则产生输出:
• 如果两个输入位相同,则输出为111;
• 如果两个输入位不同,则输出为000。
对于两个整数A和B,它们的同或结果是通过将A和B转换为二进制表示,然后对每个位进行同或运算得到的。
输入描述:
第一行输入 n m (2≤n≤200000,1≤m≤30)
接下来是n个整数a1,a2,a3……an(保证ai <2^m)
输出描述:
输出一个整数,这个整数是在这个数组任意两个数同或的最大值
示例1
输入
复制
4 3 7 5 1 3
输出
复制
5
说明
1在这台电脑中为001,3在这台电脑中为011,同或为101=5。
思路讲解:
这道题要我们求同或的最大值,我们都知道同或是二进制位运算,同或呢是异或的非,因此,我们有知道1^a 等于 a的非,所以呢,只需要将两数异或然后再与全1的数即(2的m次幂-1 )进行异或就可以得到 两数同或得结果了。
知道了如何计算同或,那么怎么才行使得同或的结果最大呢,我们都知道,同或运算的规则是相同为1,那么如何使结果最大呢,我们就让数字从小到大进行排序,然后相邻的两数进行同或即可,
观察可可以发现,相邻的同或结果才是最大的,相邻两数位数最接近
代码实现:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<int> a(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a.begin(),a.end());
int ans=0;
for(int i=1;i<n;i++)
{
ans=max(ans,((1<<m)-1)^a[i]^a[i-1]);
}
cout<<ans<<endl;
return 0;
}