Numbers of Length N having digits A and B and whose sum of digits contain only digits A and B
Given three positive integers N, A and B. The task is to count the numbers of length N containing only digits A and B and whose sum of digits also contains the digits A and B only. Print the answer modulo 109 + 7.
Examples:
Input: N = 3, A = 1, B = 3
Output: 1
Possible numbers of length 3 are 113, 131, 111, 333, 311, 331 and so on…
But only 111 is a valid number since its sum of digits is 3 (contains digits A and B only)
Input: N = 10, A = 2, B = 3
Output: 165
Approach: The idea is to express the sum of digits of the number as a linear equation in two variables i.e.
S = X * A + Y * B where A and B are the given digits and X and Y are the frequencies of these digits respectively.
Since, the sum of (X + Y) should be equal to N (length of the number) according to the given condition, we can replace Y with (N – X) and the equation reduces to S = X * A + (N – X) * B. Thus, X = (S – N * B) / (A – B).
Now, we can iterate over all possible values of S where minimum value of S is an N-digit number where all digits are 1 and maximum value of S is an N-digit number where all digits are 9 and check if the current value contains only digits A and B. Find the values of X and Y using the above formula for valid current S. Since, we can also permute the digits count of numbers will be (N! / X! Y!) for current value S. Add this result to the final answer.
Note: Use Fermat Little Theorem to compute n! % p.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; const int MAX = 1e5 + 5; const int MOD = 1e9 + 7; #define ll long long // Function that returns true if the num contains // a and b digits only int check( int num, int a, int b) { while (num) { int rem = num % 10; num /= 10; if (rem != a && rem != b) return 0; } return 1; } // Modular Exponentiation ll power(ll x, ll y) { ll ans = 1; while (y) { if (y & 1) ans = (ans * x) % MOD; y >>= 1; x = (x * x) % MOD; } return ans % MOD; } // Function to return the modular inverse // of x modulo MOD int modInverse( int x) { return power(x, MOD - 2); } // Function to return the required count // of numbers ll countNumbers( int n, int a, int b) { ll fact[MAX], inv[MAX]; ll ans = 0; // Generating factorials of all numbers fact[0] = 1; for ( int i = 1; i < MAX; i++) { fact[i] = (1LL * fact[i - 1] * i); fact[i] %= MOD; } // Generating inverse of factorials modulo // MOD of all numbers inv[MAX - 1] = modInverse(fact[MAX - 1]); for ( int i = MAX - 2; i >= 0; i--) { inv[i] = (inv[i + 1] * (i + 1)); inv[i] %= MOD; } // Keeping a as largest number if (a < b) swap(a, b); // Iterate over all possible values of s and // if it is a valid S then proceed further for ( int s = n; s <= 9 * n; s++) { if (!check(s, a, b)) continue ; // Check for invalid cases in the equation if (s < n * b || (s - n * b) % (a - b) != 0) continue ; int numDig = (s - n * b) / (a - b); if (numDig > n) continue ; // Find answer using combinatorics ll curr = fact[n]; curr = (curr * inv[numDig]) % MOD; curr = (curr * inv[n - numDig]) % MOD; // Add this result to final answer ans = (ans + curr) % MOD; } return ans; } // Driver Code int main() { int n = 3, a = 1, b = 3; cout << countNumbers(n, a, b); return 0; } |
C
// C implementation of the approach #include <stdio.h> #include<math.h> const int MAX = 1e5 + 5; const int MOD = 1e9 + 7; #define ll long long // Function that returns true if the num contains // a and b digits only int check( int num, int a, int b) { while (num) { int rem = num % 10; num /= 10; if (rem != a && rem != b) return 0; } return 1; } // Modular Exponentiation ll power(ll x, ll y) { ll ans = 1; while (y) { if (y & 1) ans = (ans * x) % MOD; y >>= 1; x = (x * x) % MOD; } return ans % MOD; } // Function to return the modular inverse // of x modulo MOD int modInverse( int x) { return power(x, MOD - 2); } // Function to return the required count // of numbers ll countNumbers( int n, int a, int b) { ll fact[MAX], inv[MAX]; ll ans = 0; // Generating factorials of all numbers fact[0] = 1; for ( int i = 1; i < MAX; i++) { fact[i] = (1LL * fact[i - 1] * i); fact[i] %= MOD; } // Generating inverse of factorials modulo // MOD of all numbers inv[MAX - 1] = modInverse(fact[MAX - 1]); for ( int i = MAX - 2; i >= 0; i--) { inv[i] = (inv[i + 1] * (i + 1)); inv[i] %= MOD; } // Keeping a as largest number if (a < b){ //Swapping a and b a=a+b; b=a-b; a=a-b; } // Iterate over all possible values of s and // if it is a valid S then proceed further for ( int s = n; s <= 9 * n; s++) { if (!check(s, a, b)) continue ; // Check for invalid cases in the equation if (s < n * b || (s - n * b) % (a - b) != 0) continue ; int numDig = (s - n * b) / (a - b); if (numDig > n) continue ; // Find answer using combinatorics ll curr = fact[n]; curr = (curr * inv[numDig]) % MOD; curr = (curr * inv[n - numDig]) % MOD; // Add this result to final answer ans = (ans + curr) % MOD; } return ans; } // Driver Code int main() { int n = 3, a = 1, b = 3; printf ( "%lld" ,countNumbers(n, a, b)); return 0; } // This code is contributed by allwink45. |
Java
// Java implementation of the approach class GFG { static int MAX = ( int )(1E5 + 5 ); static long MOD = ( long )(1E9 + 7 ); // Function that returns true if the num contains // a and b digits only static boolean check( long num, long a, long b) { while (num > 0 ) { long rem = num % 10 ; num /= 10 ; if (rem != a && rem != b) return false ; } return true ; } // Modular Exponentiation static long power( long x, long y) { long ans = 1 ; while (y > 0 ) { if ((y & 1 ) > 0 ) ans = (ans * x) % MOD; y >>= 1 ; x = (x * x) % MOD; } return ans % MOD; } // Function to return the modular inverse // of x modulo MOD static long modInverse( long x) { return power(x, MOD - 2 ); } // Function to return the required count // of numbers static long countNumbers( long n, long a, long b) { long [] fact = new long [MAX]; long [] inv = new long [MAX]; long ans = 0 ; // Generating factorials of all numbers fact[ 0 ] = 1 ; for ( int i = 1 ; i < MAX; i++) { fact[i] = ( 1 * fact[i - 1 ] * i); fact[i] %= MOD; } // Generating inverse of factorials modulo // MOD of all numbers inv[MAX - 1 ] = modInverse(fact[MAX - 1 ]); for ( int i = MAX - 2 ; i >= 0 ; i--) { inv[i] = (inv[i + 1 ] * (i + 1 )); inv[i] %= MOD; } // Keeping a as largest number if (a < b) { long x = a; a = b; b = x; } // Iterate over all possible values of s and // if it is a valid S then proceed further for ( long s = n; s <= 9 * n; s++) { if (!check(s, a, b)) continue ; // Check for invalid cases in the equation if (s < n * b || (s - n * b) % (a - b) != 0 ) continue ; int numDig = ( int )((s - n * b) / (a - b)); if (numDig > n) continue ; // Find answer using combinatorics long curr = fact[( int )n]; curr = (curr * inv[numDig]) % MOD; curr = (curr * inv[( int )n - numDig]) % MOD; // Add this result to final answer ans = (ans + curr) % MOD; } return ans; } // Driver Code public static void main (String[] args) { long n = 3 , a = 1 , b = 3 ; System.out.println(countNumbers(n, a, b)); } } // This code is contributed by mits |
Python3
# Python 3 implementation of the approach MAX = 100005 ; MOD = 1000000007 # Function that returns true if the num # contains a and b digits only def check(num, a, b): while (num): rem = num % 10 num = int (num / 10 ) if (rem ! = a and rem ! = b): return 0 return 1 # Modular Exponentiation def power(x, y): ans = 1 while (y): if (y & 1 ): ans = (ans * x) % MOD y >> = 1 x = (x * x) % MOD return ans % MOD # Function to return the modular # inverse of x modulo MOD def modInverse(x): return power(x, MOD - 2 ) # Function to return the required # count of numbers def countNumbers(n, a, b): fact = [ 0 for i in range ( MAX )] inv = [ 0 for i in range ( MAX )] ans = 0 # Generating factorials of all numbers fact[ 0 ] = 1 for i in range ( 1 , MAX , 1 ): fact[i] = ( 1 * fact[i - 1 ] * i) fact[i] % = MOD # Generating inverse of factorials # modulo MOD of all numbers inv[ MAX - 1 ] = modInverse(fact[ MAX - 1 ]) i = MAX - 2 while (i > = 0 ): inv[i] = (inv[i + 1 ] * (i + 1 )) inv[i] % = MOD i - = 1 # Keeping a as largest number if (a < b): temp = a a = b b = temp # Iterate over all possible values of s and # if it is a valid S then proceed further for s in range (n, 9 * n + 1 , 1 ): if (check(s, a, b) = = 0 ): continue # Check for invalid cases in the equation if (s < n * b or (s - n * b) % (a - b) ! = 0 ): continue numDig = int ((s - n * b) / (a - b)) if (numDig > n): continue # Find answer using combinatorics curr = fact[n] curr = (curr * inv[numDig]) % MOD curr = (curr * inv[n - numDig]) % MOD # Add this result to final answer ans = (ans + curr) % MOD return ans # Driver Code if __name__ = = '__main__' : n = 3 a = 1 b = 3 print (countNumbers(n, a, b)) # This code is contributed by # Surendra_Gangwar |
C#
// C# implementation of the approach using System; class GFG { static long MAX = ( long )(1E5 + 5); static long MOD = ( long )(1E9 + 7); // Function that returns true if the num contains // a and b digits only static bool check( long num, long a, long b) { while (num > 0) { long rem = num % 10; num /= 10; if (rem != a && rem != b) return false ; } return true ; } // Modular Exponentiation static long power( long x, long y) { long ans = 1; while (y > 0) { if ((y & 1) > 0) ans = (ans * x) % MOD; y >>= 1; x = (x * x) % MOD; } return ans % MOD; } // Function to return the modular inverse // of x modulo MOD static long modInverse( long x) { return power(x, MOD - 2); } // Function to return the required count // of numbers static long countNumbers( long n, long a, long b) { long [] fact = new long [MAX]; long [] inv = new long [MAX]; long ans = 0; // Generating factorials of all numbers fact[0] = 1; for ( long i = 1; i < MAX; i++) { fact[i] = (1 * fact[i - 1] * i); fact[i] %= MOD; } // Generating inverse of factorials modulo // MOD of all numbers inv[MAX - 1] = modInverse(fact[MAX - 1]); for ( long i = MAX - 2; i >= 0; i--) { inv[i] = (inv[i + 1] * (i + 1)); inv[i] %= MOD; } // Keeping a as largest number if (a < b) { long x = a; a = b; b = x; } // Iterate over all possible values of s and // if it is a valid S then proceed further for ( long s = n; s <= 9 * n; s++) { if (!check(s, a, b)) continue ; // Check for invalid cases in the equation if (s < n * b || (s - n * b) % (a - b) != 0) continue ; long numDig = (s - n * b) / (a - b); if (numDig > n) continue ; // Find answer using combinatorics long curr = fact[n]; curr = (curr * inv[numDig]) % MOD; curr = (curr * inv[n - numDig]) % MOD; // Add this result to final answer ans = (ans + curr) % MOD; } return ans; } // Driver Code static void Main() { long n = 3, a = 1, b = 3; Console.WriteLine(countNumbers(n, a, b)); } } // This code is contributed by mits |
Javascript
<script> // JavaScript implementation of the approach const MAX = (5); let MOD = (7); // Function that returns true if the num contains // a and b digits only function check(num , a , b) { while (num > 0) { var rem = num % 10; num = parseInt(num/10); if (rem != a && rem != b) return false ; } return true ; } // Modular Exponentiation function power(x , y) { var ans = 1; while (y > 0) { if ((y & 1) > 0) ans = (ans * x) % MOD; y >>= 1; x = (x * x) % MOD; } return ans % MOD; } // Function to return the modular inverse // of x modulo MOD function modInverse(x) { return power(x, MOD - 2); } // Function to return the required count // of numbers function countNumbers(n , a , b) { var fact = Array(MAX).fill(0); var inv = Array(MAX).fill(0); var ans = 0; // Generating factorials of all numbers fact[0] = 1; for ( var i = 1; i < MAX; i++) { fact[i] = (1 * fact[i - 1] * i); fact[i] %= MOD; } // Generating inverse of factorials modulo // MOD of all numbers inv[MAX - 1] = modInverse(fact[MAX - 1]); for (i = MAX - 2; i >= 0; i--) { inv[i] = (inv[i + 1] * (i + 1)); inv[i] %= MOD; } // Keeping a as largest number if (a < b) { var x = a; a = b; b = x; } // Iterate over all possible values of s and // if it is a valid S then proceed further for (s = n; s <= 9 * n; s++) { if (!check(s, a, b)) continue ; // Check for invalid cases in the equation if (s < n * b || (s - n * b) % (a - b) != 0) continue ; var numDig = parseInt( ((s - n * b) / (a - b))); if (numDig > n) continue ; // Find answer using combinatorics var curr = fact[parseInt(n)]; curr = (curr * inv[numDig]) % MOD; curr = (curr * inv[parseInt( n - numDig)]) % MOD; // Add this result to final answer ans = (ans + curr) % MOD; } return ans; } // Driver Code var n = 3, a = 1, b = 3; document.write(countNumbers(n, a, b)); // This code contributed by umadevi9616 </script> |
1
Time Complexity: O(Max)
Auxiliary Space: O(Max), since Max extra space has been taken.
Please Login to comment...