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.
Steps to solve the problem:
- Initialize fact[MAX] and inv[MAX] arrays with all elements set to 0 and initialize ans to 0.
- Generate factorials of all numbers from 0 to MAX-1 and store them in the fact array.
- Generate inverses of factorials modulo MOD of all numbers from MAX-1 to 0 and store them in the inv array.
- If a is less than b, swap their values.
- Iterate through s from n to 9n:
- If check(s, a, b) returns false, continue to the next value of s.
- If s is less than n times b or if (s – n * b) modulo (a – b) is not equal to 0, continue to the next value of s.
- Calculate numDig as (s – n * b) divided by (a – b).
- If numDig is greater than n, continue to the next value of s.
- Calculate curr as follows:
- Set curr to fact[n].
- Multiply curr by inv[numDig] modulo MOD.
- Multiply curr by inv[n – numDig] modulo MOD.
- Add curr to ans modulo MOD.
- Return ans as the required answer.
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 onlyint 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 Exponentiationll 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 MODint modInverse(int x){ return power(x, MOD - 2);}// Function to return the required count// of numbersll 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 Codeint 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 onlyint 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 Exponentiationll 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 MODint modInverse(int x){ return power(x, MOD - 2);}// Function to return the required count// of numbersll 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 Codeint 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 approachclass 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 onlystatic 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 Exponentiationstatic 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 MODstatic long modInverse(long x){ return power(x, MOD - 2);}// Function to return the required count// of numbersstatic 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 Codepublic 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 approachMAX = 100005;MOD = 1000000007# Function that returns true if the num # contains a and b digits onlydef check(num, a, b): while (num): rem = num % 10 num = int(num / 10) if (rem != a and rem != b): return 0 return 1# Modular Exponentiationdef 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 MODdef modInverse(x): return power(x, MOD - 2)# Function to return the required # count of numbersdef 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 Codeif __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 approachusing 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 onlystatic 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 Exponentiationstatic 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 MODstatic long modInverse(long x){ return power(x, MOD - 2);}// Function to return the required count// of numbersstatic 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 Codestatic 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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



