已知非负数和、异或和求两数

题目来源: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;
}
posted @ 2020-06-23 10:03  菁芜  阅读(307)  评论(0编辑  收藏  举报