📌  相关文章
📜  通过重新排列两个二进制字符串形成的不同XOR的计数

📅  最后修改于: 2021-06-25 10:15:14             🧑  作者: Mango

给定两个长度为N的二进制字符串AB ,任务是通过任意重新排序两个二进制字符串找到可能的不同XOR数。由于数字可以足够大,因此求模10 9 + 7的数字

例子:

方法:

  • 既然我们知道
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0


因此,要在结果字符串的任何索引处将XOR值设为1,输入字符串在该索引处的奇数必须为1s

  • 现在,我们将尝试以某种方式重新排列二进制字符串,即最大索引数的奇数为1。可以通过以下示例将其可视化:

  • 因此,从上面的观察中,我们的想法是通过对字符串进行重新排序来找到1的最小和最大数目
    • 查找最大的’1’:当形成最大的{0,1}和{1,0}对时,结果中将出现最大的’1’。所以,
  • 要找到最小的“ 1”:这种情况可以看做是结果中最大“ 0”的倒数。类似地,当形成最大{0,0}和{1,1}对时,结果中将出现最大“ 0”。所以,
  • 1的所有组合都可以在这两个数字(最小值和最大值)之间形成,两者之差为2。
  • 最后,可以通过从最小1到最大1的组合数(步长为2)来计算获得结果的可能方法的总数。

下面是上述方法的实现:

C++14
// C++ program to find the number of
// distinct XORs formed by rearranging
// two binary strings
#include 
 
using namespace std;
 
// function to compute modulo power
long long power(long long a, long long b, long long mod)
{
    long long aa = 1;
    while(b)
    {
 
        if(b&1)
        {
            aa = aa * a;
            aa %= mod;
        }
        a = a * a;
        a %= mod;
        b /= 2;
    }
 
    return aa;
}
 
// Function to calculate nCr % p
// over a range
long long nCrRangeSum(long long n, long long r1,
                    long long r2, long long p)
{
 
    // Initialize the numerator
    // and denominator
    long long num = 1, den = 1;
 
    // Initialize the sum
    long long sum = 0;
 
    // nC0 is 1
    if (r1 == 0)
        sum += 1;
 
    // Traversing till the range
    for (int i = 0; i < r2; i++)
    {
 
        // Computing the numerator
        num = (num * (n - i)) % p;
 
        // Computing the denominator
        den = (den * (i + 1)) % p;
 
        // If 'i' lies between the given range
        // and is at an even long long interval from
        // the starting range because
        // the combinations at a step of 2
        // is required
        if(i - r1 >= -1 and (i - r1 + 1) % 2 == 0)
        {
 
            // Computing nCr and adding the value
            // sum
            sum += (num * power(den, p - 2, p)) % p;
            sum %= p;
        }
        }
    return sum;
}
 
// Function to find the number of
// distinct XORs formed by
// rearranging two binary strings
int compute(string A, string B, int N)
{
 
    // Initializing the count variable
    // to 0
    int c0A = 0, c1A = 0, c0B = 0, c1B = 0;
 
    // Iterating through A
    for (char c:A) {
 
        // Increment the c1A variable
        // if the current element is 1
        if (c == '1')
            c1A += 1;
 
        // Increment the c0A variable
        // if the current element is 0
        else if (c == '0')
            c0A += 1;
        }
 
    // Iterating through B
    for (char c:B){
 
        // Increment the c1B variable
        // if the current element is 1
        if (c == '1')
            c1B += 1;
 
        // Increment the c0A variable
        // if the current element is 0
        else if (c == '0')
            c0B += 1;
        }
 
    // Finding the minimum number of '1's in the XOR
    // and the maximum number of '1's in the XOR
    int max1xor = min(c0A, c1B) + min(c1A, c0B);
    int min1xor = N - min(c0B, c0A) - min(c1A, c1B);
 
    // Compute the number of combinations between
    // the minimum number of 1's and the maximum
    // number of 1's and perform % with 10^9 + 7
    int ans = nCrRangeSum(N, min1xor, max1xor, 1000000000 + 7);
 
    // Return the answer
    return ans;
}
 
// Driver code
int main()
{
    long long N = 3;
    string A = "010";
    string B = "100";
     
    cout << compute(A, B,N);
    return 0;
}
 
// This code is contributed by mohit kumar 29


Java
// JAVA program to find the number of
// distinct Bitwise XORs formed by rearranging
// two binary strings
 
class GFG
{
    // function to compute modular exponentiation
    // i.e. to find (a^b) % mod
    static long mod_power(long a, long b,
                          long mod)
    {
        long result = 1l;
        while(b > 0)
        {
            if((b&1) == 0) // b is even
            {
                result = a * a;
                a %= mod;
                b /= 2;
            }
            else // b is odd
            {
                result = result * a;
                result %= mod;
            }
        }
        return result;
    }
 
    // method to evaluate nCr modulo p
    // over an interval
    static long nCr_RangeSum(long n, long r1,
                            long r2, long p)
    {
 
        // initializing numerator
        // and denominator
        long num = 1, den = 1;
 
        // initialize the sum
        long sum = 0l;
 
        // nC0 is 1
        if(r1 == 0)
            sum += 1l;
 
        // Iterating through the range
        for(int i = 0; i < r2; i++)
        {
 
            // computing the numerator
            num = (num * (n - i)) % p;
             
            // computing the denominator
            den = (den * (i + 1)) % p;
 
            // If 'i' lies between the given range
            // and is at an even interval from 
            // the starting range because 
            // the combinations at a step of 2 
            // is required
            if(i - r1 >= -1 && (i - r1 + 1) % 2 == 0)
            {
                // Computing nCr and adding the value
                // to the sum  
                sum += (num * mod_power(den, p - 2, p)) % p;
                sum %= p;
            }
        }
        return sum;
    }
     
    // method to find the number of
    // distinct XORs formed by
    // rearrangement of two binary strings
    static long compute(String A, String B, int N)
    {
        // Initializing the counter variables
        // to 0
        int c0A = 0, c1A = 0, c0B = 0, c1B = 0;
 
        // Iterating through A's characters
        for (char c : A.toCharArray())
        {
 
            // Increment the c1A variable
            // if the current element is 1
            if (c == '1')
                c1A += 1;
 
            // Increment the c0A variable
            // if the current element is 0
            else if (c == '0')
                c0A += 1;
            }
 
        // Iterating through B's characters
        for (char c : B.toCharArray())
        {
 
            // Increment the c1B variable
            // if the current element is 1
            if (c == '1')
                c1B += 1;
 
            // Increment the c0A variable
            // if the current element is 0
            else if (c == '0')
                c0B += 1;
        }
        // Finding the minimum number of '1's in the XOR
        // and the maximum number of '1's in the XOR
        int max1xor = Math.min(c0A, c1B) + Math.min(c1A, c0B);
        int min1xor = N - Math.min(c0B, c0A) - Math.min(c1A, c1B);
 
        // Compute the number of combinations between
        // the minimum number of 1's and the maximum
        // number of 1's and perform modulo with 10^9 + 7
        long ans =  nCr_RangeSum(N, min1xor, max1xor, 1000000000 + 7);
 
        // Return the answer
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 3; // length of each string
         
        String A = "010";
        String B = "100";
         
        System.out.print(compute(A, B, N));
    }
}
 
// This Code is contributed by Soumitri Chattopadhyay.


Python3
# Python3 program to find the number of
# distinct XORs formed by rearranging
# two binary strings
 
# Function to calculate nCr % p
# over a range
def nCrRangeSum(n, r1, r2, p):
 
    # Initialize the numerator
    # and denominator
    num = den = 1
 
    # Initialize the sum
    sum = 0
     
    # nC0 is 1
    if r1 == 0:
        sum += 1
 
    # Traversing till the range
    for i in range(r2):
 
        # Computing the numerator
        num = (num * (n - i)) % p
 
        # Computing the denominator
        den = (den * (i + 1)) % p
 
        # If 'i' lies between the given range
        # and is at an even interval from
        # the starting range because
        # the combinations at a step of 2
        # is required
        if(i - r1 >= -1 and (i - r1 + 1) % 2 == 0):
 
            # Computing nCr and adding the value
            # sum
            sum += (num * pow(den, p - 2, p)) % p
            sum %= p
    return sum
 
# Function to find the number of
# distinct XORs formed by
# rearranging two binary strings
def compute(A, B):
 
    # Initializing the count variable
    # to 0
    c0A = c1A = c0B = c1B = 0
 
    # Iterating through A
    for c in A:
 
        # Increment the c1A variable
        # if the current element is 1
        if c == '1':
            c1A += 1
 
        # Increment the c0A variable
        # if the current element is 0
        elif c == '0':
            c0A += 1
 
    # Iterating through B
    for c in B:
 
        # Increment the c1B variable
        # if the current element is 1
        if c == '1':
            c1B += 1
 
        # Increment the c0A variable
        # if the current element is 0
        elif c == '0':
            c0B += 1
 
    # Finding the minimum number of '1's in the XOR
    # and the maximum number of '1's in the XOR
    max1xor = min(c0A, c1B) + min(c1A, c0B)
    min1xor = N - min(c0B, c0A) - min(c1A, c1B)
     
    # Compute the number of combinations between
    # the minimum number of 1's and the maximum
    # number of 1's and perform % with 10^9 + 7
    ans = nCrRangeSum(N, min1xor, max1xor, 10**9 + 7)
 
    # Return the answer
    return ans
 
# Driver code
if __name__ == "__main__":
 
    N = 3
    A = "010"
    B = "100"
 
    print(compute(A, B))


C#
// C# program to find the number of 
// distinct Bitwise XORs formed by
// rearranging two binary strings
using System;
 
class GFG{
     
// Function to compute modular exponentiation
// i.e. to find (a^b) % mod 
static long mod_power(long a, long b,
                      long mod)
{
    long result = 1;
     
    while (b > 0)
    {
        if ((b & 1) == 0) // b is even
        {
            result = a * a;
            a %= mod;
            b /= 2;
        }
        else // b is odd
        {
            result = result * a;
            result %= mod;
        }
    }
    return result;
}
 
// Function to evaluate nCr modulo p
// over an interval
static long nCr_RangeSum(long n, long r1, 
                         long r2, long p)
{
     
    // Initializing numerator 
    // and denominator
    long num = 1, den = 1;
 
    // Initialize the sum 
    long sum = 0;
 
    // nC0 is 1
    if (r1 == 0)
        sum += 1;
 
    // Iterating through the range
    for(int i = 0; i < r2; i++)
    {
         
        // Computing the numerator
        num = (num * (n - i)) % p;
           
        // Computing the denominator
        den = (den * (i + 1)) % p; 
 
        // If 'i' lies between the given range 
        // and is at an even interval from  
        // the starting range because  
        // the combinations at a step of 2  
        // is required 
        if (i - r1 >= -1 && (i - r1 + 1) % 2 == 0) 
        {
             
            // Computing nCr and adding the value 
            // to the sum   
            sum += (num * mod_power(
                  den, p - 2, p)) % p; 
            sum %= p; 
        }
    }
    return sum;
}
   
// Function to find the number of distinct
// XORs formed by rearrangement of two
// binary strings
static long compute(string A, string B, int N)
{
     
    // Initializing the counter variables 
    // to 0 
    int c0A = 0, c1A = 0, c0B = 0, c1B = 0; 
 
    // Iterating through A's characters 
    foreach(char c in A) 
    { 
         
        // Increment the c1A variable 
        // if the current element is 1 
        if (c == '1') 
            c1A += 1; 
 
        // Increment the c0A variable 
        // if the current element is 0 
        else if (c == '0') 
            c0A += 1; 
    } 
 
    // Iterating through B's characters 
    foreach(char c in B)
    { 
         
        // Increment the c1B variable 
        // if the current element is 1 
        if (c == '1') 
            c1B += 1; 
 
        // Increment the c0A variable 
        // if the current element is 0 
        else if (c == '0') 
            c0B += 1; 
    } 
     
    // Finding the minimum number of
    // '1's in the XOR and the maximum
    // number of '1's in the XOR 
    int max1xor = Math.Min(c0A, c1B) +
                  Math.Min(c1A, c0B); 
    int min1xor = N - Math.Min(c0B, c0A) -
                      Math.Min(c1A, c1B); 
 
    // Compute the number of combinations
    // between the minimum number of 1's
    // and the maximum number of 1's and
    // perform modulo with 10^9 + 7 
    long ans =  nCr_RangeSum(N, min1xor,
                 max1xor, 1000000000 + 7);
 
    // Return the answer 
    return ans; 
}
 
// Driver code
static public void Main()
{
     
    // Length of each string
    int N = 3;
       
    string A = "010"; 
    string B = "100"; 
       
    Console.WriteLine(compute(A, B, N));
}
}
 
// This code is contributed by offbeat


输出:
4