题意:
给你n和m以及由n异或(1-m)组成的集合,问你这个集合中没有出现过的最小的非负整数是多少。
思路:
n
⨁
n\bigoplus
n⨁
x
=
k
x=k
x=k,且x为1到m中的每一个数
由交换律可得:n
⨁
\bigoplus
⨁k
=
x
=x
=x,而x为1到m中的每一个数,
所以要找到集合{
n
⨁
n\bigoplus
n⨁
x
=
k
x=k
x=k}中出现的最小非负整数,就是要找到一个最小的k,满足n
⨁
\bigoplus
⨁k
≥
\geq
≥ m+1。
现在要找到这个k,可以对每一个二进制位进行判断。
从最高位开始,如果该位置上n为1,m+1为0,则k在该位置上应该为1;如果该位置上n为0,m+1为1,那么k在该位置上为0,且k后面的位置都为0…
#include<iostream>
#include<cmath>
#include<mem.h>
#include<algorithm>
#define endl '\n'
using namespace std;
#define ll long long
int ans[100];
int k[100];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(k,0,sizeof(k));
memset(ans,0,sizeof(ans));
ll n,m;
cin>>n>>m;
if(n > m)
{
cout<<0<<endl;
}
else
{
int num = 0;
m++;
while(m)
{
ans[++num] = m%2;
m = m>>1;
}
int cnt = 0;
while(n)
{
k[++cnt] = n%2;
n = n>>1;
}
for(int i = 1; i <= cnt/2; i++)
{
int op = k[i];
k[i] = k[cnt-i+1];
k[cnt-i+1] = op;
}
for(int i = 1; i <= num/2; i++)
{
int op = ans[i];
ans[i] = ans[num-i+1];
ans[num-i+1] = op;
}
int flag = 0;
for(int i = 1; i <= cnt; i++)
{
if(flag)
{
ans[num-cnt+i] = 0;
continue;
}
if(k[i] && !ans[num-cnt+i])
{
ans[num-cnt+i] = 0;
flag = 1;
}
else if(!k[i] && ans[num-cnt+i])
{
ans[num-cnt+i] = 1;
}
else if(k[i] && ans[num-cnt+i])
{
ans[num-cnt+i] = 0;
}
}
ll res = 0;
for(int i = 1; i <= num; i++)
{
res += ans[i]*pow(2,num-i);
}
cout<<res<<endl;
}
}
}