已知非负数和、异或和求两数
题目来源:2020-06-22:已知两个非负数的异或值为M,两数之和为N,求这两个数?
题目描述
已知两非负数的和 M
、异或和 N
,求这两个数。
题解
暴力枚举 , O(n)
vector<int> TestXorAndSum(int M, int N) {
int a, b;
for(a = 0; a <= N; a++) {
if(a ^ (N - a) == M)
return {a, N - a};
}
return {};
}
法二:假定两数是 a、b,则题意为 a + b = n
, a^b=m
. 那么,有 a&b=(n-m)>>1
。所以,可以简单的构造出一个解。(当然,可能有多个解,这里只构造了一个)
vector<int> TestXorAndSum(int M, int N) {
if(N - M < 0)
return {};
int and_sum = (N - M) >> 1;
int a = and_sum;
int b = and_sum;
a ^= M;
return {a, b};
return {};
}
那么,如何求全部解?枚举子集即可。 for(int i = sta; i; i = i−1 & sta) // 枚举 sta 的子集,注意空集!
// 暴力求全部解很好做
vector<vector<int> > TestXorAndSum_1(int M, int N) {
vector<vector<int>>ans;
for(int a = 0; a <= N; a++) {
if((a ^ (N - a)) == M) {
ans.push_back({a, N - a});
}
}
return ans;
}
vector<vector<int> > TestXorAndSum_2(int M, int N) {
vector<vector<int>>ans;
if(N - M < 0)
return ans;
const int and_sum = (N - M) >> 1;
for(int i = M,a,b; ; i = i - 1 & M) {// 枚举 xor_sum 的子集
a = and_sum ^ i;
b = and_sum ^ i ^ M;
ans.push_back({a, b});
if(!i) break;
}
sort(ans.begin(), ans.end());
ans.erase(unique(ans.begin(), ans.end()), ans.end());
return ans;
}