Count N digits numbers with sum divisible by K

Given two integers N and K, the task is to count all N digits numbers whose sum of digits is divisible by K.

Examples:

 Input: N = 2, K = 7
Output: 12
Explanation: 2 digits numbers with sum divisible by 7 are: {16, 25, 34, 43, 52, 59, 61, 68, 70, 77, 86, 95}.
Therefore, the required output is 12.

Input: N = 1, K = 2
Output: 4

Naive Approach: The simplest approach is to traverse all the numbers from the range [10(N – 1), 10N – 1] and check if the sum of all the digits of a number that lies within the range is divisible by K or not. For every number for which the condition is found to be true, increase count. Finally, print the count.
Time Complexity: O(10N – 10N – 1 – 1)
Auxiliary Space: O(1)



Efficient Approach: The idea is to use Digit DP technique to optimize the above approach. Below is the recurrence relation:

CountNum(N, sum, st) = \sum^{9}_{i=0} countNum(N - 1, (sum + i)\mod K, st)

sum: represents sum of digits
st: check if a number contains any leading 0.

Follow the steps below to solve the problem:

  1. Initialize a 3D array dp[N][K][st] to compute and store the values of all subproblems of the above recurrence relation.
  2. Finally, return the value of dp[N][sum%K][st].
  3. C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ Program to implement
    // the above approach
      
    #include <bits/stdc++.h>
    using namespace std;
    #define M 1000
      
    // Function to count the N digit numbers
    // whose sum is divisible by K
    int countNum(int N, int sum, int K,
                 bool st, int dp[M][M][2])
    {
        // Base case
        if (N == 0 and sum == 0) {
            return 1;
        }
        if (N < 0) {
            return 0;
        }
      
        // If already computed
        // subproblem occurred
        if (dp[N][sum][st] != -1) {
            return dp[N][sum][st];
        }
      
        // Store the count of N digit numbers
        // whoe sum is divisible by K
        int res = 0;
      
        // Check if the number does not contan
        // any leading 0.
        int start = st == 1 ? 0 : 1;
      
        // Recurrence relation
        for (int i = start; i <= 9; i++) {
            res += countNum(N - 1, (sum + i) % K,
                         K, (st | i > 0), dp);
        }
      
        return dp[N][sum][st] = res;
    }
      
    // Driver Code
    int main()
    {
        int N = 2, K = 7;
      
        // Stores the values of
        // overlapping subproblems
        int dp[M][M][2];
      
        memset(dp, -1, sizeof(dp));
      
        cout << countNum(N, 0, K, 0, dp);
    }

    chevron_right

    
    

    Output:

    12
    

    Time Complexity:O(10*N*K)
    Auxiliary Space: O(N*K)

    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 Posts:


    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.