位运算之谜
题目描述
a+b的值为x,a&b的值为y,首先需要判断能否有一组a,b满足当前的情况,如果有,那么求出a xor b,否则输出-1
(其中a,b>0)
输入描述:
第一行为一个正整数t,表示组数
(
t
<
=
2
×
1
0
5
t<=2×10^5
t<=2×105)(
t
<
=
2
×
1
0
5
t<=2×10^5
t<=2×105)
接下来t行,每一行有两个整数x,y接下来t行,每一行有两个整数x,y
(
0
<
=
x
,
y
<
=
1
×
1
0
18
0<=x,y<=1×10^{18}
0<=x,y<=1×1018)(
0
<
=
x
,
y
<
=
1
×
1
0
18
0<=x,y<=1×10^{18}
0<=x,y<=1×1018)
输出描述:
对于每一组数据,按题意输出a xor b或者-1
示例1
输入
1
2 1
输出
0
示例2
输入
1
2 2
输出
-1
题解:
a&b=y说明a,b的二进制至少大于等于y,所以a+b=x>=2y才有有结果,否则输出-1,
a^b为x减去全部二进制位相同的即x-2y,并且(x-2y)&y!=0才行因为当x=3,y=1,这种也是不符合情况的。
我们想,a^b 即:把a、b中所有相同的项的位都变成0,剩下的都是a、
b中不相同的位,即变成1。而 a & b 即:将a、b中相同的保留下来,原来是0算完之后还是0,原来是1算完之后还是1,这也就刚好与 a ^ b 中的情况相反。所以 a ^ b即分别对a、b减去 a & b即得到答案。所以 a ^ b = x - 2 * y。
c++ AC 代码
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int main()
{
int t;
ll x, y;
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &x, &y);
if (x < 2 * y || (x - 2 * y) & y != 0)
{
puts("-1");
continue;
}
else
printf("%d\n", x - 2 * y);
}
system("pause");
return 0;
}