给定两个数的XOR和SUM,如何找到满足它们的对的数量?

时间:2016-04-07 13:26:46

标签: algorithm math

我认为这个问题可能有点令人困惑。所以,我会先尝试解释一下。

假设给出了两个数的XOR和SUM。 (请注意,有多对可能满足此要求。)

例如,如果XOR为5且SUM为9,则满足SUM和XOR的4对。它们是(2, 7)(3, 6)(6, 3)(7, 2)。所以2+7=92^7=5

我只想找到满足SUM和XOR的数量对。所以在我提到的例子中,答案4就足够了。我不需要知道哪些配对满足它们。

我从here处理了这个问题。

我检查了答案here。它提供的O(n)解决方案还不够。

有一个编辑提供了解决这个问题的方法。它可以找到here。 (寻找627A的解决方案)

问题在于我无法理解解决方案。根据我的总结,他们使用了这样的公式,
(如果有两个数字a和b)那么, a+b = (a XOR b) + (a AND b)*2

我如何到达那个?其余的步骤对我来说不清楚。

如果有人能就如何解决这个问题或解释他们的解决方案提出想法,请帮助。

2 个答案:

答案 0 :(得分:9)

a+b = (a XOR b) + (a AND b)*2想象为进行二进制加法时会发生什么。在您的示例中,a = 010b = 111

 010
 111
 ---
1001 = 101 + 100

对于每个位,您添加来自ab0+0=00+1=11+0=11+1=0的位,这正是a XOR b 加上来自前一次加法的进位位,即如果ab的前两位都是1,那么我们也将其添加。正是(a AND b)*2。(请记住乘以2是左移。)

使用该等式,我们可以计算a AND b

现在要计算你想要的数字,我们逐个查看a XOR ba AND b的每个位,并将所有可能性相乘。 (让我为a[i]的{​​{1}}编写i

  • 如果aa[i] XOR b[i] = 0,则a[i] AND b[i] = 0。这个位只有一种可能性。

  • 如果a[i] = b[i] = 0a[i] XOR b[i] = 0,则a[i] AND b[i] = 1。这个位只有一种可能性。

  • 如果a[i] = b[i] = 1a[i] XOR b[i] = 1,则a[i] AND b[i] = 0a[i] = 1,反之亦然。两种可能性。

  • 无法b[i] = 0a[i] XOR b[i] = 1

从您的示例a[i] AND b[i] = 1a XOR b = 101开始。我们得到了答案a AND b = 010

答案 1 :(得分:3)

a AND b是两个数字中的位。所以这些都是总和的两倍。 a XOR b是仅存在于其中一个数字中的位,因此这些数字只应在总和中计算一次。

以下是一个例子:

  • a = 4 = 1*2^2 + 0*2^1 + 0*2^0 (or just 100)
  • b = 13 = 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0 (or just 1101)
  • a + b = (1*2^2 + 0*2^1 + 0*2^0) + (1*2^3 + 1*2^2 + 0*2^1 + 1*2^0) = 1*2^3 + 2*2^2 + 0*2^1 + 1*2^0

请注意最后一行中两个数字(2^2)中的位如何在总和中计算两次,而其余位只计算一次!

要解决您的问题,您需要找到所有对(a,b)加起来的总和。你想要做的是:

  1. 从SUM中减去XOR值。您将离开2*(a AND b)
  2. 除以2.您现在拥有应在a和b中设置的所有位。
  3. 由于您具有XOR值,因此您确切地知道应该在 a和b的一个中设置哪些位,而您刚刚计算的AND值是应该在中设置的位。 他们。因此,您列出了分别在a或b中设置位的所有排列。
  4. 继续上一个例子:

    • a AND b = 0100(始终设置)
    • a XOR b = 1001(我们需要尝试这些的所有排列)

    我们将这些排列作为解决方案:

    • a = 0100 + 0000 = 0100, b = 0100 + 1001 = 1101 => (4, 13)
    • a = 0100 + 0001 = 0101, b = 0100 + 1000 = 1100 => (5, 12)
    • a = 0100 + 1000 = 1100, b = 0100 + 0001 = 0101 => (12, 5)
    • a = 0100 + 1001 = 1101, b = 0100 + 0000 = 0100 => (13, 4)