Related Articles
Kth number exceeding N whose sum of its digits divisible by M
• Last Updated : 21 Nov, 2020

Given the integers N, K and M, the task is to find the Kth number greater than N whose sum of digits is divisible by M.

Examples:

Input: N = 6, K = 5, M = 5
Output: 32
Explanation:
The number greater than N = 6 with the sum of their digits divisible by 5 are {14, 19, 23, 28, 32, …}. The Kth number i.e., the 5th number is 32.

Input: N = 40, K = 4,  M = 5
Output: 55
Explanation:
The number greater than N = 40 with the sum of their digits divisible by 5 are {41, 46, 50, 55, …}. The Kth number i.e., the 4th number is 55.

Naive Approach: The simplest approach is to check every number greater than N and if the sum of its digits is divisible by M, increment the counter by 1. Keep checking the number until the counter becomes equal to K

Time Complexity: O(K)
Auxiliary Space: O(1)

Efficient Approach: The idea is to use Dynamic Programming and Binary Search. Follow the below steps to solve the problem:

• First, create a recursive memorized function to find the total number of integers smaller than or equal to S having the sum of digits divisible by M as shown below:

The dp transitions will be:

dp(S, index, sum, tight, M) = dp(index+1, (sum+i)%M, tight, M) where,

• S is given limit for which all numbers smaller than or equal to S with the sum of digits divisible by M needs to be found.
• index is the current index for which a digit needs to be placed.
• sum takes the values from 0 to 4.
• Base condition is, if index becomes greater than the length of S and sum is divisible by M, return 1.
• M is the divisor.

If the previous digit already placed such that it becomes smaller than S then

• tight will become equal to 0.
• i will iterate from 0 to 9.

If all the previous digits match with the corresponding digits in S, then

• tight will become 1, which denotes that the number is still not become smaller than S.
• i will iterate from 0 to digit S[index].
• Now using Binary Search, where the lower limit will be N+1 and the upper limit will be some large integer.
• Initialize a variable left for storing the total numbers smaller than or equal to N whose sum of digits is divisible by M.
• Find the midpoint of the lower and the upper limit and then find the numbers smaller than or equal midpoint whose sum of digits is divisible by M using the above dp function. Let it be right.
• If left + K is equals to right then, update the answer as mid and set the upper limit as midpoint – 1.
• Otherwise, if left + K is smaller than right, set the upper limit as midpoint-1.
• If left + K is greater than right, set the lower limit as midpoint+1.
• Repeat the above steps, while the lower limit is smaller than or equal to the upper limit.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Initialize dp array` `int` `dp;`   `// Function to find the numbers <= S` `// having digits sum divisible by M` `int` `solve(string s, ``int` `index, ``int` `sum, ` `                    ``int` `tight, ``int` `z)` `{` `    `  `    ``// Base Case` `    ``if` `(index >= s.size()) ` `    ``{` `        ``if` `(sum % z == 0)` `            ``return` `1;` `            `  `        ``return` `0;` `    ``}`   `    ``// Visited state` `    ``if` `(dp[index][sum][tight] != -1)` `        ``return` `dp[index][sum][tight];`   `    ``// Store answer` `    ``int` `ans = 0;`   `    ``// If number still does not` `    ``// become smaller than S` `    ``if` `(tight == 1) ` `    ``{` `        `  `        ``// Find limit` `        ``int` `l = s[index] - ``'0'``;`   `        ``// Iterate through all` `        ``// the digits` `        ``for``(``int` `i = 0; i <= l; i++) ` `        ``{` `            `  `            ``// If current digit is limit` `            ``if` `(i == l) ` `            ``{` `                ``ans += solve(s, index + 1,` `                                 ``(sum + i) % z, 1, z);` `            ``}`   `            ``// Number becomes smaller than S` `            ``else` `{` `                ``ans += solve(s, index + 1, ` `                                 ``(sum + i) % z, 0, z);` `            ``}` `        ``}` `    ``}` `    ``else` `    ``{` `        `  `        ``// If number already becomes` `        ``// smaller than S` `        ``for``(``int` `i = 0; i <= 9; i++)` `            ``ans += solve(s, index + 1,` `                             ``(sum + i) % z, 0, z);` `    ``}`   `    ``// Return and store the answer` `    ``// for the current state` `    ``return` `dp[index][sum][tight] = ans;` `}`   `// Function to find the Kth number` `// > N whose sum of the digits is` `// divisible by M` `int` `search(``int` `n, ``int` `k, ``int` `z)` `{` `    `  `    ``// Initialize lower limit` `    ``int` `low = n + 1;`   `    ``// Initialize upper limit` `    ``int` `high = 1e9;`   `    ``// Mask dp states unvisited` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``// Numbers <= N except 0 with` `    ``// digits sum divisible by M` `    ``int` `left = solve(to_string(n),` `                     ``0, 0, 1, z) - 1;`   `    ``// Initialize answer with -1` `    ``int` `ans = -1;` `    ``while` `(low <= high) ` `    ``{` `        `  `        ``// Calculate mid` `        ``int` `mid = low + (high - low) / 2;`   `        ``// Mark dp states unvisited` `        ``memset``(dp, -1, ``sizeof``(dp));`   `        ``// Numbers < mid with digits` `        ``// sum divisible by M` `        ``int` `right = solve(to_string(mid), ` `                          ``0, 0, 1, z) - 1;`   `        ``// If the current mid is` `        ``// satisfy the condition` `        ``if` `(left + k == right) ` `        ``{` `            `  `            ``// Might be the answer` `            ``ans = mid;`   `            ``// Update upper limit` `            ``high = mid - 1;` `        ``}` `        ``else` `if` `(left + k < right) ` `        ``{` `            `  `            ``// Update upper limit` `            ``high = mid - 1;` `        ``}` `        ``else` `        ``{` `            `  `            ``// Update lower limit` `            ``low = mid + 1;` `        ``}` `    ``}`   `    ``// Return the answer` `    ``return` `ans;` `}`   `// Driver Code` `int` `main()` `{` `    `  `    ``// Given N, K, and M` `    ``int` `N = 40;` `    ``int` `K = 4;` `    ``int` `M = 2;` `    `  `    ``// Function Call` `    ``cout << search(N, K, M) << endl;` `}`   `// This code is contributed by bolliranadheer`

## Java

 `// Java program for the above approach`   `import` `java.util.*;` `public` `class` `Main {`   `    ``static` `int` `dp[][][];`   `    ``// Function to find the Kth number` `    ``// > N whose sum of the digits is` `    ``// divisible by M` `    ``public` `static` `int` `search(` `        ``int` `n, ``int` `k, ``int` `z)` `    ``{`   `        ``// Initialize dp array` `        ``dp = ``new` `int``[``100000` `+ ``1``][z][``2``];`   `        ``// Initialize lower limit` `        ``int` `low = n + ``1``;`   `        ``// Initialize upper limit` `        ``int` `high = Integer.MAX_VALUE / ``2``;`   `        ``// Mask dp states unvisited` `        ``clear();`   `        ``// Numbers <= N except 0 with` `        ``// digits sum divisible by M` `        ``int` `left = solve(n + ``""``, ``0``,` `                         ``0``, ``1``, z)` `                   ``- ``1``;`   `        ``// Initialize answer with -1` `        ``int` `ans = -``1``;` `        ``while` `(low <= high) {`   `            ``// Calculate mid` `            ``int` `mid = low + (high - low) / ``2``;`   `            ``// Mark dp states unvisited` `            ``clear();`   `            ``// Numbers < mid with digits` `            ``// sum divisible by M` `            ``int` `right = solve(mid + ``""``, ``0``,` `                              ``0``, ``1``, z)` `                        ``- ``1``;`   `            ``// If the current mid is` `            ``// satisfy the condition` `            ``if` `(left + k == right) {`   `                ``// Might be the answer` `                ``ans = mid;`   `                ``// Update upper limit` `                ``high = mid - ``1``;` `            ``}` `            ``else` `if` `(left + k < right) {`   `                ``// Update upper limit` `                ``high = mid - ``1``;` `            ``}` `            ``else` `{`   `                ``// Update lower limit` `                ``low = mid + ``1``;` `            ``}` `        ``}`   `        ``// Return the answer` `        ``return` `ans;` `    ``}`   `    ``// Function to find the numbers <= S` `    ``// having digits sum divisible by M` `    ``public` `static` `int` `solve(` `        ``String s, ``int` `index, ``int` `sum,` `        ``int` `tight, ``int` `z)` `    ``{` `        ``// Base Case` `        ``if` `(index >= s.length()) {` `            ``if` `(sum % z == ``0``)` `                ``return` `1``;` `            ``return` `0``;` `        ``}`   `        ``// Visited state` `        ``if` `(dp[index][sum][tight] != -``1``)` `            ``return` `dp[index][sum][tight];`   `        ``// Store answer` `        ``int` `ans = ``0``;`   `        ``// If number still does not` `        ``// become smaller than S` `        ``if` `(tight == ``1``) {`   `            ``// Find limit` `            ``int` `l = s.charAt(index) - ``'0'``;`   `            ``// Iterate through all` `            ``// the digits` `            ``for` `(``int` `i = ``0``; i <= l; i++) {`   `                ``// If current digit is limit` `                ``if` `(i == l) {` `                    ``ans += solve(s, index + ``1``,` `                                 ``(sum + i) % z,` `                                 ``1``, z);` `                ``}`   `                ``// Number becomes smaller than S` `                ``else` `{` `                    ``ans += solve(s, index + ``1``,` `                                 ``(sum + i) % z,` `                                 ``0``, z);` `                ``}` `            ``}` `        ``}` `        ``else` `{`   `            ``// If number already becomes` `            ``// smaller than S` `            ``for` `(``int` `i = ``0``; i <= ``9``; i++)` `                ``ans += solve(s, index + ``1``,` `                             ``(sum + i) % z, ``0``,` `                             ``z);` `        ``}`   `        ``// Return and store the answer` `        ``// for the current state` `        ``return` `dp[index][sum][tight] = ans;` `    ``}`   `    ``// Function to clear the states` `    ``public` `static` `void` `clear()` `    ``{` `        ``for` `(``int` `i[][] : dp) {` `            ``for` `(``int` `j[] : i)` `                ``Arrays.fill(j, -``1``);` `        ``}` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String args[])` `    ``{` `        ``// Given N, K, and M` `        ``int` `N = ``40``;` `        ``int` `K = ``4``;` `        ``int` `M = ``2``;`   `        ``// Function Call` `        ``System.out.println(search(N, K, M));` `    ``}` `}`

## Python3

 `# Python program for the` `# above approach`   `# Initialize dp array` `dp ``=` `[[[]]]`   `# Function to find the ` `# numbers <= S having ` `# digits sum divisible ` `# by M` `def` `solve(s, index, ` `          ``sum``,tight, z):`   `    ``# Base Case` `    ``if` `(index >``=` `len``(s)):    ` `        ``if` `(``sum` `%` `z ``=``=` `0``):` `            ``return` `1`   `        ``return` `0`   `    ``# Visited state` `    ``if` `(dp[index][``sum``][tight] !``=` `-``1``):` `        ``return` `dp[index][``sum``][tight]`   `    ``# Store answer` `    ``ans ``=` `0`   `    ``# If number still does not` `    ``# become smaller than S` `    ``if``(tight ``=``=` `1``):`   `        ``# Find limit` `        ``l ``=` `int``(``ord``(s[index]) ``-` `                ``ord``(``'0'``))`   `        ``# Iterate through all` `        ``# the digits` `        ``for` `i ``in` `range``(``0``, l ``+` `1``):` `            `  `            ``# If current digit is ` `            ``# limit` `            ``if` `(i ``=``=` `l):` `            `  `                ``ans ``+``=` `solve(s, index ``+` `1``,` `                            ``(``sum` `+` `i) ``%` `z, ` `                             ``1``, z)` `            `  `            ``# Number becomes smaller` `            ``# than S` `            ``else``:` `                ``ans ``+``=` `solve(s, index ``+` `1``,` `                            ``(``sum` `+` `i) ``%` `z, ` `                             ``0``, z)`   `    ``else``:` `    `  `        ``# If number already becomes` `        ``# smaller than S` `        ``for` `i ``in` `range``(``0``,``10``):` `        `  `            ``ans ``+``=` `solve(s, index ``+` `1``,` `                        ``(``sum` `+` `i) ``%` `z, ` `                         ``0``, z)` `    `  `    ``# Return and store the answer` `    ``# for the current state` `    ``dp[index][``sum``][tight] ``=` `ans` `    ``return` `ans`   `# Function to find the Kth number` `# > N whose sum of the digits is` `# divisible by M` `def` `search(n, k, z):`   `    ``global` `dp` `    ``dp ``=` `[[[``-``1``, ``-``1``] ``for` `j ``in` `range``(z)] ` `                    ``for` `i ``in` `range``(``100001``)]`   `    ``# Initialize lower limit` `    ``low ``=` `n ``+` `1`   `    ``# Initialize upper limit` `    ``high ``=` `1000000009`   `    ``# Numbers <= N except 0 with` `    ``# digits sum divisible by M` `    ``left ``=` `solve(``str``(n), ``0``, ` `                 ``0``, ``1``, z) ``-` `1`   `    ``# Initialize answer with -1` `    ``ans ``=` `-``1` `    ``while` `(low <``=` `high):`   `        ``# Calculate mid` `        ``mid ``=` `low ``+` `(high ``-` `                     ``low) ``/``/` `2`   `        ``# Mark dp states unvisited` `        ``dp ``=` `[[[``-``1``, ``-``1``] ``for` `j ``in` `range``(z)] ` `                        ``for` `i ``in` `range``(``100000``)]`   `        ``# Numbers < mid with digits` `        ``# sum divisible by M` `        ``right ``=` `solve(``str``(mid), ``0``, ` `                      ``0``, ``1``, z) ``-` `1`   `        ``# If the current mid is` `        ``# satisfy the condition` `        ``if` `(left ``+` `k ``=``=` `right):`   `            ``# Might be the answer` `            ``ans ``=` `mid`   `            ``# Update upper limit` `            ``high ``=` `mid ``-` `1` `        `  `        ``elif` `(left ``+` `k < right):` `        `  `            ``# Update upper limit` `            ``high ``=` `mid ``-` `1` `        `  `        ``else``:`   `            ``# Update lower limit` `            ``low ``=` `mid ``+` `1`   `    ``# Return the answer` `    ``return` `ans`   `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `    `  `    ``# Given N, K, and M` `    ``N ``=` `40` `    ``K ``=` `4` `    ``M ``=` `2`   `    ``# Function Call` `    ``print``(search(N, K, M))`   `# This code is contributed by Rutvik_56`

## C#

 `// C# program for the above approach` `using` `System;`   `class` `GFG{`   `static` `int` `[,,]dp;`   `// Function to find the Kth number` `// > N whose sum of the digits is` `// divisible by M` `public` `static` `int` `search(``int` `n, ``int` `k, ` `                         ``int` `z)` `{` `    `  `    ``// Initialize dp array` `    ``dp = ``new` `int``[100000 + 1, z, 2];`   `    ``// Initialize lower limit` `    ``int` `low = n + 1;`   `    ``// Initialize upper limit` `    ``int` `high = ``int``.MaxValue / 2;`   `    ``// Mask dp states unvisited` `    ``Clear(z);`   `    ``// Numbers <= N except 0 with` `    ``// digits sum divisible by M` `    ``int` `left = solve(n + ``""``, 0,` `                     ``0, 1, z) - 1;`   `    ``// Initialize answer with -1` `    ``int` `ans = -1;` `    ``while` `(low <= high) ` `    ``{` `        `  `        ``// Calculate mid` `        ``int` `mid = low + (high - low) / 2;` `        `  `        ``// Mark dp states unvisited` `        ``Clear(z);` `        `  `        ``// Numbers < mid with digits` `        ``// sum divisible by M` `        ``int` `right = solve(mid + ``""``, 0,` `                          ``0, 1, z) - 1;`   `        ``// If the current mid is` `        ``// satisfy the condition` `        ``if` `(left + k == right) ` `        ``{` `            `  `            ``// Might be the answer` `            ``ans = mid;`   `            ``// Update upper limit` `            ``high = mid - 1;` `        ``}` `        ``else` `if` `(left + k < right)` `        ``{` `            `  `            ``// Update upper limit` `            ``high = mid - 1;` `        ``}` `        ``else` `        ``{` `            `  `            ``// Update lower limit` `            ``low = mid + 1;` `        ``}` `    ``}` `    `  `    ``// Return the answer` `    ``return` `ans;` `}`   `// Function to find the numbers <= S` `// having digits sum divisible by M` `public` `static` `int` `solve(String s, ``int` `index,` `                        ``int` `sum, ``int` `tight,` `                        ``int` `z)` `{` `    `  `    ``// Base Case` `    ``if` `(index >= s.Length)` `    ``{` `        ``if` `(sum % z == 0)` `            ``return` `1;` `            `  `        ``return` `0;` `    ``}`   `    ``// Visited state` `    ``if` `(dp[index, sum, tight] != -1)` `        ``return` `dp[index, sum, tight];`   `    ``// Store answer` `    ``int` `ans = 0;`   `    ``// If number still does not` `    ``// become smaller than S` `    ``if` `(tight == 1)` `    ``{` `        `  `        ``// Find limit` `        ``int` `l = s[index] - ``'0'``;`   `        ``// Iterate through all` `        ``// the digits` `        ``for``(``int` `i = 0; i <= l; i++)` `        ``{` `            `  `            ``// If current digit is limit` `            ``if` `(i == l) ` `            ``{` `                ``ans += solve(s, index + 1,` `                            ``(sum + i) % z,` `                             ``1, z);` `            ``}` `            `  `            ``// Number becomes smaller than S` `            ``else` `            ``{` `                ``ans += solve(s, index + 1,` `                            ``(sum + i) % z,` `                             ``0, z);` `            ``}` `        ``}` `    ``}` `    ``else` `    ``{` `        `  `        ``// If number already becomes` `        ``// smaller than S` `        ``for``(``int` `i = 0; i <= 9; i++)` `            ``ans += solve(s, index + 1,` `                        ``(sum + i) % z, 0,` `                         ``z);` `    ``}` `    `  `    ``// Return and store the answer` `    ``// for the current state` `    ``return` `dp[index, sum, tight] = ans;` `}`   `// Function to clear the states` `public` `static` `void` `Clear(``int` `z)` `{` `    ``for``(``int` `i = 0; i < 100001; i++)` `    ``{` `        ``for``(``int` `j = 0; j < z; j++)` `        ``{` `            ``for``(``int` `l = 0; l < 2; l++)` `                ``dp[i, j, l] = -1;` `        ``}` `    ``}` `}`   `// Driver Code` `public` `static` `void` `Main(String []args)` `{` `    `  `    ``// Given N, K, and M` `    ``int` `N = 40;` `    ``int` `K = 4;` `    ``int` `M = 2;` `    `  `    ``// Function Call` `    ``Console.WriteLine(search(N, K, M));` `}` `}`   `// This code is contributed by gauravrajput1`

Output

```48
```

Time Complexity: O(log(INT_MAX))
Auxiliary Space: O(K * M * log(INT_MAX))

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :