 Open in App
Not now

# Kth number exceeding N whose sum of its digits divisible by M

• Last Updated : 16 Jul, 2021

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`

## Javascript

 ``

Output

`48`

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

My Personal Notes arrow_drop_up