📌  相关文章
📜  从它们的总和与XOR中找出两个数字

📅  最后修改于: 2021-05-06 23:11:44             🧑  作者: Mango

给定两个数XY的总和与异或,st和和异或\in [0, 2^{64}-1] ,我们需要找到使X值最小的数字。

例子 :

Input : S = 17
        X = 13
Output : a = 2
         b = 15

Input : S = 1870807699 
        X = 259801747
Output : a = 805502976
         b = 1065304723

Input : S = 1639
        X = 1176
Output : No such numbers exist

一个简单的解决方案是使用给定的XOR生成所有可能的对。要生成所有对,我们可以遵循以下规则。

  1. 如果X [i]为1,则a [i]和b [i]应该都不同,我们有两种情况。
  2. 如果X [i]为0,则a [i]和b [i]应该相同。我们有两种情况。

    因此,我们生成2 ^ n个可能的对,其中n是X中的位数。然后对于每对,我们检查其总和是否为S。

    一个有效的解决方案基于以下事实。

    因此我们可以找到A =(S – X)/ 2。

    一旦找到A,就可以使用以下规则找到“ a”和“ b”的所有位。

    1. 如果X [i] = 0且A [i] = 0,则a [i] = b [i] =0。对于该位,只有一种可能性。
    2. 如果X [i] = 0且A [i] = 1,则a [i] = b [i] = 1。
    3. 如果X [i] = 1且A [i] = 0,则(a [i] = 1且b [i] = 0)或(a [i] = 0且b [i] = 1),我们可以选择两者中的任何一个。
    4. 如果X [i] = 1且A [i] = 1,则结果不可能(注X [i] = 1表示不同的位)

    令总和为S,XOR为X。

    下面是上述方法的实现:

    C++
    // CPP program to find two numbers with
    // given Sum and XOR such that value of
    // first number is minimum.
    #include 
    using namespace std;
      
    // Function that takes in the sum and XOR
    // of two numbers and generates the two 
    // numbers such that the value of X is
    // minimized
    void compute(unsigned long int S, 
                unsigned long int X)
    {
        unsigned long int A = (S - X)/2;
      
        int a = 0, b = 0;
      
        // Traverse through all bits
        for (int i=0; i<8*sizeof(S); i++)
        {
            unsigned long int Xi = (X & (1 << i));
            unsigned long int Ai = (A & (1 << i));
            if (Xi == 0 && Ai == 0)
            {
                // Let us leave bits as 0.
            }
            else if (Xi == 0 && Ai > 0)
            {
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            }
            else if (Xi > 0 && Ai == 0)
            {
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0.
            }
            else // (Xi == 1 && Ai == 1)
            {
                cout << "Not Possible";
                return;
            }
        }
      
        cout << "a = " << a << endl << "b = " << b;
    }
      
    // Driver function
    int main()
    {
        unsigned long int S = 17, X = 13;
        compute(S, X);
        return 0;
    }


    Java
    // Java program to find two numbers with 
    // given Sum and XOR such that value of 
    // first number is minimum. 
    class GFG {
      
    // Function that takes in the sum and XOR 
    // of two numbers and generates the two 
    // numbers such that the value of X is 
    // minimized 
    static void compute(long S, long  X) 
    { 
        long A = (S - X)/2; 
        int a = 0, b = 0; 
            final int LONG_FIELD_SIZE     = 8;
      
        // Traverse through all bits 
        for (int i=0; i<8*LONG_FIELD_SIZE; i++) 
        { 
            long Xi = (X & (1 << i)); 
            long Ai = (A & (1 << i)); 
            if (Xi == 0 && Ai == 0) 
            { 
                // Let us leave bits as 0. 
            } 
            else if (Xi == 0 && Ai > 0) 
            { 
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            } 
            else if (Xi > 0 && Ai == 0) 
            { 
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0. 
            } 
            else // (Xi == 1 && Ai == 1) 
            { 
                System.out.println("Not Possible"); 
                return; 
            } 
        } 
      
        System.out.println("a = " + a +"\nb = " + b); 
    } 
      
    // Driver function 
        public static void main(String[] args) {
            long S = 17, X = 13; 
        compute(S, X); 
      
        }
    }
    // This code is contributed by RAJPUT-JI


    Python3
    # Python program to find two numbers with
    # given Sum and XOR such that value of
    # first number is minimum.
      
      
    # Function that takes in the sum and XOR
    # of two numbers and generates the two 
    # numbers such that the value of X is
    # minimized
    def compute(S, X):
        A = (S - X)//2
        a = 0
        b = 0
      
        # Traverse through all bits
        for i in range(64):
            Xi = (X & (1 << i))
            Ai = (A & (1 << i))
            if (Xi == 0 and Ai == 0):
                # Let us leave bits as 0.
                pass
                  
            elif (Xi == 0 and Ai > 0):
                a = ((1 << i) | a) 
                b = ((1 << i) | b) 
              
            elif (Xi > 0 and Ai == 0):
                a = ((1 << i) | a) 
                # We leave i-th bit of b as 0.
      
            else: # (Xi == 1 and Ai == 1)
                print("Not Possible")
                return
      
        print("a = ",a)
        print("b =", b)
      
      
    # Driver function
    S = 17
    X = 13
    compute(S, X)
      
    # This code is contributed by ankush_953


    C#
    // C# program to find two numbers with 
    // given Sum and XOR such that value of 
    // first number is minimum. 
    using System;
      
    public class GFG {
      
    // Function that takes in the sum and XOR 
    // of two numbers and generates the two 
    // numbers such that the value of X is 
    // minimized 
    static void compute(long S, long  X) 
    { 
        long A = (S - X)/2; 
        int a = 0, b = 0; 
       
      
        // Traverse through all bits 
        for (int i=0; i<8*sizeof(long); i++) 
        { 
            long Xi = (X & (1 << i)); 
            long Ai = (A & (1 << i)); 
            if (Xi == 0 && Ai == 0) 
            { 
                // Let us leave bits as 0. 
            } 
            else if (Xi == 0 && Ai > 0) 
            { 
                a = ((1 << i) | a); 
                b = ((1 << i) | b); 
            } 
            else if (Xi > 0 && Ai == 0) 
            { 
                a = ((1 << i) | a); 
      
                // We leave i-th bit of b as 0. 
            } 
            else // (Xi == 1 && Ai == 1) 
            { 
                Console.WriteLine("Not Possible"); 
                return; 
            } 
        } 
      
        Console.WriteLine("a = " + a +"\nb = " + b); 
    } 
      
    // Driver function 
        public static void Main() {
            long S = 17, X = 13; 
            compute(S, X); 
        }
    }
    // This code is contributed by RAJPUT-JI


    输出

    a = 15
    b = 2
    

    上述方法的时间复杂度O(b)其中b是S中的位数。