Pairs whose concatenation contain all digits

Given an array of n numbers. The task is to find the number of pairs that can be taken from the given which on concatenation will contain all the digits from 0 to 9.

Examples:

Input : num[][] = { “129300455”, “5559948277”, “012334556”, “56789”, “123456879” }
Output : 5
{“129300455”, “56789”}, { “129300455”, “123456879”}, {“5559948277”, “012334556”},
{“012334556”, “56789”}, {“012334556”, “123456879”} are the pair which contain all the digits from 0 to 9 on concatenation.

Note: Number of digit in each of the number can be 10^6.

The idea is to represent each number as the mask of 10 bits such that if it contains digit i at least once then ith bit will be set in the mask.
For example,
let n = 4556120 then 0th, 1st, 2nd, 4th, 5th, 6th bits will be set in mask.
Thus, mask = (0001110111)2 = (119)10
Now, for every mask m from 0 to 2^10 – 1, we will store the count of the number of numbers having the mask of their number equals to m.
So, we will make an array, say cnt[], where cnt[i] stores the count of the number of numbers whose mask is equal to i. Pseudocode for this:

for (i = 0; i < (1 << 10); i++)
  cnt[i] = 0;

for (i = 1; i <= n; i++)
{
  string x = p[i];
  int mask  = 0;
  for (j = 0; j < x.size(); j++)  
    mask |= (1 << (x[j] - '0';);
  
  
  cnt[mask]++;
}

A pair of numbers will have all the digit from 0 to 9 if every bits from 0 to 9 is set in the bitwise OR of maskof both the number, i.e if it’s equal to (1111111111)2</sub) = (1023)10

Now, we will iterate over all pairs of masks whose biwise OR is equal to 1023 and add the number of ways.

Below is C++ implementation of this approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP Program to find number of pairs whose
// concatenation contains all digits from 0 to 9.
#include <bits/stdc++.h>
using namespace std;
#define N 20
  
// Function to return number of pairs whose
// concatenation contain all digits from 0 to 9
int countPair(char str[N][N], int n)
{
    int cnt[1 << 10] = { 0 };
  
    // making the mask for each of the number.
    for (int i = 0; i < n; i++) {
  
        int mask = 0;
        for (int j = 0; str[i][j] != '\0'; ++j) 
            mask |= (1 << (str[i][j] - '0'));        
        cnt[mask]++;
    }
     
    // for each of the possible pair which can 
    // make OR value equal to 1023
    int ans = 0;
    for (int m1 = 0; m1 <= 1023; m1++)
        for (int m2 = 0; m2 <= 1023; m2++)
            if ((m1 | m2) == 1023) {
  
                // finding the count of pair 
                // from the given numbers.
                ans += ((m1 == m2) ? 
                       (cnt[m1] * (cnt[m1] - 1)) : 
                       (cnt[m1] * cnt[m2]));
            }
  
    return ans / 2;
}
  
// Driven Program
int main()
{
    int n = 5;
    char str[][N] = { "129300455", "5559948277",
               "012334556", "56789", "123456879" };
    cout << countPair(str, n) << endl;
    return 0;
}

chevron_right


Output:

5

Complexity : O(n + 2^10 * 2^10)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.